J'ai un widget Flutter avec une disposition de colonne qui a deux conteneurs, dont l'un a un ListView.builder . Lorsque la page s'affiche, j'obtiens un
Débordement inférieur de 169 pixels
et je ne sais pas comment y remédier.
J'ai cherché des solutions sur Google et j'ai essayé diverses choses comme envelopper un ou plusieurs des Container dans le widget dans un widget Expanded , mais cela ne fonctionne pas non plus. Si j'enveloppe uniquement le Container qui contient le FutureBuilder dans un Expanded , alors le ListView ne fonctionne pas t rendu du tout et je vois des erreurs comme:
Widget build(BuildContext context) {
return Container(
child: Column(children: <Widget>[
Container(
height: 40,
color: Colors.grey.withOpacity(0.5),
child: Padding(
padding: const EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: TextField(
autofocus: false,
controller: searchFilterController,
keyboardType: TextInputType.text,
maxLines: 1,
decoration: InputDecoration(
border: InputBorder.none,
filled: true,
fillColor: Colors.white.withOpacity(1),
hintText: 'Search',
suffixIcon: Icon(
Icons.search,
color: Colors.grey,
)),
onChanged: (value) {
filter = value;
}))),
Container(
child: FutureBuilder<UserPantry>(
future: UserPantryDao.getUserPantry(widget.userId),
builder: (context, snapshot) {
if (snapshot.hasData) {
widget.ingredientList.clear();
if (filter == null || filter.trim() == "") {
widget.ingredientList.addAll(snapshot.data.ingredients);
} else {
for (UserIngredient ingredient in snapshot.data.ingredients) {
if (ingredient.ingredient.name
.toLowerCase()
.contains(filter.toLowerCase())) {
widget.ingredientList.add(ingredient);
}
}
}
return ListView.builder(
shrinkWrap: true,
itemCount: widget.ingredientList.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(
widget.ingredientList[index].ingredient.name,
style: TextStyle(fontSize: 20.0),
));
});
} else if (snapshot.hasError) {
print(snapshot.error);
return Text(
"An error occurred while loading your pantry. Please try again.");
}
//By default just show an empty container.
return Container();
},
))
]));
}
Voici à quoi ressemble la fonction de construction de mon Widget:
I/flutter ( 3516): Another exception was thrown: RenderFlex children have non-zero flex but incoming height constraints are unbounded. I/flutter ( 3516): Another exception was thrown: RenderBox was not laid out: RenderFlex#0caf9 relayoutBoundary=up2 NEEDS-PAINT I/flutter ( 3516): Another exception was thrown: RenderBox was not laid out: RenderFlex#963f4 relayoutBoundary=up1 NEEDS-PAINT I/flutter ( 3516): Another exception was thrown: NoSuchMethodError: The method '<=' was called on null.
4 Réponses :
Enveloppez simplement votre FutureBuilder dans un widget Expanded et supprimez le Container car vous n'en avez pas du tout besoin ici.
Expanded(
child: FutureBuilder<UserPantry>(
future: UserPantryDao.getUserPantry(widget.userId),
...
Cela se produit parce que vous donnez des contraintes illimitées à la ListView . Une autre option consisterait à ajouter une contrainte de hauteur au parent ListView , telle que la définition de la hauteur dans le Container à quelque chose.
C'est l'une des choses que j'ai déjà essayées, mais quand je fais cela, toute la page est vierge et je vois ces erreurs dans la console: I / flutter (5471): Une autre exception a été levée: RenderBox n'a pas été présenté: RenderFlex # 350b4 relayoutBoundary = up2 NEEDS-PAINT I / flutter (5471): Une autre exception a été levée: RenderBox n'a pas été présenté: RenderFlex # 3fe57 relayoutBoundary = up1 NEEDS-PAINT I / flutter (5471): Une autre exception a été lancée: NoSuchMethodError: The method ' <= 'a été appelé sur null.
Je n'ai pas tout votre arbre. Comme vous l'avez en ce moment, cela devrait fonctionner. Quoi qu'il en soit, réglez simplement la hauteur du Container et tout devrait bien se passer.
La définition d'une hauteur sur le conteneur résout le problème, mais comment savoir quelle hauteur utiliser? Cela ne varie-t-il pas d'un appareil à l'autre?
Oui, mais vous pouvez utiliser un%, en faisant MediaQuery.of (context) .size.height * 0.5 , cela définira votre ListView pour utiliser 50% de l'écran la taille. Cependant, avec Expanded , vous ne devriez pas en avoir besoin, et cela devrait également fonctionner, car vous vous développerez pour remplir la fenêtre verticalement.
Essayez de supprimer le Container à l'extérieur et enveloppez la liste dans un fichier développé.
Comme @Miguel Ruivo a répondu, ListView doit avoir une contrainte bornée.
Widget build(BuildContext context) {
return Column(children: <Widget>[
Container(
height: 40,
color: Colors.grey.withOpacity(0.5),
child: Padding(
padding: const EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 2.0),
child: TextField(
autofocus: false,
controller: searchFilterController,
keyboardType: TextInputType.text,
maxLines: 1,
decoration: InputDecoration(
border: InputBorder.none,
filled: true,
fillColor: Colors.white.withOpacity(1),
hintText: 'Search',
suffixIcon: Icon(
Icons.search,
color: Colors.grey,
)),
onChanged: (value) {
filter = value;
}))),
Expanded(
child: FutureBuilder<UserPantry>(
future: UserPantryDao.getUserPantry(widget.userId),
builder: (context, snapshot) {
if (snapshot.hasData) {
widget.ingredientList.clear();
if (filter == null || filter.trim() == "") {
widget.ingredientList.addAll(snapshot.data.ingredients);
} else {
for (UserIngredient ingredient in snapshot.data.ingredients) {
if (ingredient.ingredient.name
.toLowerCase()
.contains(filter.toLowerCase())) {
widget.ingredientList.add(ingredient);
}
}
}
return ListView.builder(
shrinkWrap: true,
itemCount: widget.ingredientList.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(
widget.ingredientList[index].ingredient.name,
style: TextStyle(fontSize: 20.0),
));
});
} else if (snapshot.hasError) {
print(snapshot.error);
return Text(
"An error occurred while loading your pantry. Please try again.");
}
//By default just show an empty container.
return Container();
},
))
]);
}
L'emballage de ListView.separated (separatorBuilder: (context, index) => Divider (), ...) dans Expanded résoudra votre problème.
Par exemple: Expanded (enfant: ListView.separated (separatorBuilder: (context, index) => Divider (), itemCount: 1, itemBuilder: (context, index) {return Container (height: 200.0, child: ...);})
Enveloppez simplement la Liste uniquement avec Expanded .
Essayez ceci:
Column(
children: [
Container(
child: Text("data"),
color: Colors.redAccent,
),
Expanded(child: ListView.builder(itemBuilder: (context, i) {
return Text("data");
})),
],
),