ListView.builder'daki TextFields kayboluyor

Sep 02 2020

Envanter Kontrolü yapmak için Firebase Data'dan (bir "Alimentos" listesi) ListView ve her "Alimento" için miktarı düzenlemek üzere bir TextField oluşturuyorum.

Bir "Alimentos" ekranından daha azına sahip olduğumda iyi çalışıyor, ancak "Alimentos" un bazı sayfalarına sahip olduğumda, metin alanlarım kayboluyor. Bunun gerçekleştiğini anlıyorum çünkü ListView.builder yalnızca görüntü alanı içinde veya yakınında bulunan öğeleri (siz kaydırdıkça) oluşturacak, ancak bunu nasıl çözeceğimi bilmiyorum.

Textfield'ı ListView.builder Post'ta okudum , burada @Ashton Thomas Satır başına bir Özel Widget uygulamayı öneriyor, ancak bunu nasıl elde edeceğimi anlamıyorum.

Bu benim ListView.Builder'ım ...

  Widget _crearListado(BuildContext context, AlimentoBloc alimentoBloc) {

    final _size = MediaQuery.of(context).size;

    return Container(
      height: _size.height * 0.5,
      child: StreamBuilder(
          stream: alimentoBloc.alimentoStream ,
          builder: (BuildContext context, AsyncSnapshot<List<AlimentoModel>> snapshot){
            if (snapshot.hasData) {
              List<AlimentoModel> alimentos = snapshot.data;
              alimentos.sort((a, b) => a.proteina.compareTo(b.proteina));
              return Stack(
                children: <Widget>[
                  ListView.builder(
                    itemCount: alimentos.length,
                    itemBuilder: (context, i) { //Esta variable es gráfica, sólo se crea para lo que se está viendo
                      _controlList.add(new ControlInventarioModel());
                      return _crearItem(context, alimentoBloc, alimentos[i], i);
                    },

                    padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 0.0, bottom: 20.0),
                  ),
                ],
              );
            } else {
              return Center (child: Image(image: AssetImage('assets/Aplians-fish-Preloader.gif'), height: 200.0,));
            }
          },
      ),
    );
  }

Her satırın, aşağıdaki gibi (_cajaNum) sonunda bir TextField ile birlikte bir Item (_CrearItem) vardır:

  Widget _crearItem(BuildContext context, AlimentoBloc alimentoBloc, AlimentoModel alimento, int i) {

      return Card(
        color: Colors.grey[200], //color de la tarjeta
        elevation: 0.0, //sin sombra
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
        child: ListTile(
            title: Text('${alimento.nombre}', style: TextStyle(color: Theme.of(context).primaryColor, fontSize: 18.0)), subtitle: Text ('${alimento.fabricante}'), //refLoteActual
            onTap: () {},
            leading: Icon(FontAwesomeIcons.shoppingBag, color: Theme.of(context).accentColor),
            trailing: _cajaNum(context, i, alimento.idAlimento),// nuevoControlador),
        ),
      );
  }

  Widget _cajaNum(BuildContext context, int i, String idAlimento){    
    return Container(
      width: 100.0,
      height: 40.0,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(10.0),
      ),
      child: TextField(
        style: TextStyle(fontSize: 20.0),
        textAlign: TextAlign.center,
        keyboardType: TextInputType.numberWithOptions(),//decimal:false, signed: false),
        inputFormatters: <TextInputFormatter>[
              FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,2}')),
              FilteringTextInputFormatter.singleLineFormatter,
            ],
        maxLength: 5,
        onChanged: (value) {
                if(utils.isNumeric(value) && double.parse(value)>=0) {
                  _controlList[i].cantControl = double.parse(value);
                } 
                else {
                  _controlList[i].cantControl = null;
                }
                },
        onEditingComplete: () {
          FocusScope.of(context).unfocus();
        },
        onSubmitted: (value) {
        },
      ),
    ); 
  }

ListView'um kaydırmada sürekli olarak yeniden oluşturuyorsa, TextFields değerlerini nasıl koruyabilirim?

GÜNCELLEME

Metin alanlarının "kaybolduğunu" gösteren ekran görüntüleri ekliyorum ...

Yanıtlar

IqbalAbdurrazaq Dec 04 2020 at 16:54

mülkiyet TextFormField ekleyin: initialValue. benim için çalıştı, ben de aynı şeyi yaşadım.

böyle

TextField(
    style: TextStyle(fontSize: 20.0),
    initialValue: _controlList[i].cantControll ?? '0',
    onChanged: (value) {
            if(utils.isNumeric(value) && double.parse(value)>=0) {
              _controlList[i].cantControl = double.parse(value);
            } 
            else {
              _controlList[i].cantControl = null;
            }
            },
    onEditingComplete: () {
      FocusScope.of(context).unfocus();
    },
    onSubmitted: (value) {
    },
  ),

çünkü, bir sonraki tex alanını kaydırıp girdiğinizde metin alanınız yeniden oluşturulur. ancak verileriniz zaten içinde saklanıyor _controlList[i].cantControl.