Les TextFields de ListView.builder disparaissent
Pour faire un contrôle d'inventaire, je construis un ListView à partir de Firebase Data (une liste de "Alimentos") et un TextField pour éditer la quantité pour chaque "Alimento".
Cela fonctionne bien quand j'ai moins d'un écran de "Alimentos", mais quand j'ai quelques pages de "Alimentos", mes champs de texte disparaissent. Je comprends que cela se produit parce que ListView.builder ne construira que les éléments qui se trouvent dans ou près de la fenêtre (lorsque vous faites défiler), mais je ne sais pas comment le résoudre.
J'ai lu Textfield dans ListView.builder Post , où @Ashton Thomas suggère d'implémenter un widget personnalisé par ligne, mais je ne comprends pas comment l'obtenir.
Ceci est mon 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,));
}
},
),
);
}
Chaque ligne a un élément (_CrearItem) avec un TextField à sa fin (_cajaNum) comme suit:
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) {
},
),
);
}
Si mon ListView se reconstruit en continu au défilement, comment puis-je conserver les valeurs de TextFields?
MISE À JOUR
J'inclus des captures d'écran qui montrent des champs de texte "disparaissant" ...
Réponses
ajouter la propriété TextFormField: initialValue. ça a marché pour moi, j'ai aussi vécu la même chose.
comme ça
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) {
},
),
cause, votre champ de texte se reconstruit lorsque vous faites défiler et entrez le champ de texte suivant. mais vos données sont déjà stockées dans _controlList[i].cantControl.