ListView.builder의 TextFields가 사라집니다.

Sep 02 2020

인벤토리 제어를 수행하기 위해 Firebase 데이터 ( "Alimentos"목록) 및 TextField에서 ListView를 작성하여 각 "Alimento"의 수량을 편집합니다.

"Alimentos"화면보다 적 으면 잘 작동하지만 "Alimentos"페이지가 일부 있으면 텍스트 필드가 사라집니다. ListView.builder가 (스크롤 할 때) 뷰포트 안이나 근처에있는 항목 만 빌드 할 것이기 때문에 발생한다는 것을 이해하지만 해결 방법을 모르겠습니다.

@Ashton Thomas가 행당 사용자 정의 위젯 구현을 제안하는 ListView.builder Post에서 Textfield를 읽었 지만 그 방법을 이해하지 못합니다.

이것은 내 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,));
            }
          },
      ),
    );
  }

각 행에는 다음과 같이 후행 (_cajaNum)에 TextField가있는 항목 (_CrearItem)이 있습니다.

  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가 스크롤시 계속해서 다시 작성되는 경우 TextField의 값을 어떻게 유지할 수 있습니까?

최신 정보

"사라지는"텍스트 필드를 보여주는 스크린 샷을 포함합니다 ...

답변

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

원인, 스크롤하고 다음 texfield를 입력하면 텍스트 필드가 다시 작성됩니다. 하지만 데이터는 이미에 저장되어 _controlList[i].cantControl있습니다.