TextFields ใน ListView.builder หายไป

Sep 02 2020

ในการควบคุมพื้นที่โฆษณาฉันกำลังสร้าง ListView จาก Firebase Data (รายการ "Alimentos") และช่องข้อความเพื่อแก้ไขปริมาณสำหรับ "Alimento" แต่ละรายการ

ใช้งานได้ดีเมื่อฉันมีหน้าจอ "Alimentos" น้อยกว่า แต่เมื่อฉันมี "Alimentos" บางหน้าช่องข้อความของฉันก็หายไป ฉันเข้าใจว่ามันเกิดขึ้นเพราะ ListView.builder จะสร้างรายการที่อยู่ในหรือใกล้วิวพอร์ตเท่านั้น (ขณะที่คุณเลื่อน) แต่ฉันไม่รู้วิธีแก้

ฉันอ่านTextfield ใน ListView.builder Postโดยที่ @Ashton Thomas แนะนำให้ใช้ Custom Widget ต่อแถว แต่ฉันไม่เข้าใจวิธีรับ

นี่คือ ListView.Builder ของฉัน ...

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

แต่ละแถวมี Item (_CrearItem) พร้อม TextField ที่ต่อท้าย (_cajaNum) ดังต่อไปนี้:

  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 ของฉันสร้างใหม่อย่างต่อเนื่องเมื่อเลื่อนฉันจะเก็บค่าของ TextFields ได้อย่างไร

อัปเดต

ฉันรวมภาพหน้าจอที่แสดงฟิลด์ข้อความ "หายไป" ...

คำตอบ

IqbalAbdurrazaq Dec 04 2020 at 16:54

เพิ่ม TextFormField initialValueทรัพย์สิน: มันใช้ได้ผลสำหรับฉันฉันก็ประสบสิ่งเดียวกัน

แบบนี้

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

ทำให้ฟิลด์ข้อความของคุณสร้างใหม่เมื่อคุณเลื่อนและป้อนข้อมูลเท็กซ์ฟิลด์ถัดไป _controlList[i].cantControlแต่ข้อมูลของคุณจะถูกเก็บไว้แล้วใน