TextFields di ListView.builder menghilang

Sep 02 2020

Untuk melakukan Kontrol Inventaris, saya membuat ListView dari Data Firebase (daftar "Alimentos") dan TextField untuk mengedit kuantitas untuk setiap "Alimento".

Ini berfungsi dengan baik ketika saya memiliki kurang dari layar "Alimentos", tetapi ketika saya memiliki beberapa halaman "Alimentos", bidang teks saya menghilang. Saya mengerti itu terjadi karena ListView.builder hanya akan membangun item yang ada di dalam atau dekat viewport (saat Anda menggulir), tetapi saya tidak tahu cara menyelesaikannya.

Saya membaca Textfield di ListView.builder Post , di mana @Ashton Thomas menyarankan untuk menerapkan Widget Kustom per Baris, tetapi saya tidak mengerti cara mendapatkannya.

Ini adalah ListView.Builder saya ...

  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,));
            }
          },
      ),
    );
  }

Setiap baris memiliki Item (_CrearItem) dengan TextField di belakangnya (_cajaNum) sebagai berikut:

  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) {
        },
      ),
    ); 
  }

Jika ListView saya terus-menerus dibangun kembali saat menggulir, bagaimana saya bisa menyimpan nilai TextFields?

MEMPERBARUI

Saya menyertakan tangkapan layar yang menunjukkan bidang teks "menghilang" ...

Jawaban

IqbalAbdurrazaq Dec 04 2020 at 16:54

menambahkan TextFormField properti: initialValue. Ini berhasil untuk saya, saya juga mengalami hal yang sama.

seperti ini

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) {
    },
  ),

Sebab, bidang teks Anda dibangun kembali saat Anda menggulir dan memasukkan bidang teks berikutnya. tetapi data Anda sudah disimpan di _controlList[i].cantControl.