class MyHome extends StatefulWidget {
@override
State<StatefulWidget> createState() => new MyHomePage2();
}
class MyHomePage2 extends State<MyHome> {
List items = new List();
buildlist(String s) {
setState(() {
print("entered buildlist" + s);
List refresh = new List();
if (s == 'button0') {
refresh = [
new Refreshments("Watermelon", 250),
new Refreshments("Orange", 275),
new Refreshments("Pine", 300),
new Refreshments("Papaya", 225),
new Refreshments("Apple", 250),
];
} else if (s == 'button1') {
refresh = [
new Refreshments("Pina Colada", 250),
new Refreshments("Bloody Mary", 275),
new Refreshments("Long Island Ice tea", 300),
new Refreshments("Screwdriver", 225),
new Refreshments("Fusion Cocktail", 250),
];
} else if (s == 'button2') {
refresh = [
new Refreshments("Virgin Pina Colada", 250),
new Refreshments("Virgin Mary", 275),
new Refreshments("Strawberry Flush", 300),
new Refreshments("Mango Diver", 225),
new Refreshments("Peach Delight", 250),
];
} else {
refresh = [
new Refreshments("Absolute", 250),
new Refreshments("Smirnoff", 275),
new Refreshments("White Mischief", 300),
new Refreshments("Romanov", 225),
new Refreshments("Blender's Pride", 250),
];
}
for (var item in refresh) {
items.add(new ItemsList(item));
}
});
}
@override
Widget build(BuildContext context) {
var abc = MediaQuery.of(context).size;
print(abc.width);
var width = abc.width / 4;
Text text = new Text("Dev");
Text text2 = new Text("Sneha");
Text text3 = new Text("Prashant");
Text text4 = new Text("Vikesh");
var pad = const EdgeInsets.all(10.0);
Padding pad1 = new Padding(child: text, padding: pad);
Padding pad2 = new Padding(child: text2, padding: pad);
Padding pad3 = new Padding(child: text3, padding: pad);
Padding pad4 = new Padding(child: text4, padding: pad);
ListView listView = new ListView(children: <Widget>[
new Image.asset('images/party.jpg'),
pad1,
pad2,
pad3,
pad4
]);
Drawer drawer = new Drawer(child: listView);
return new Scaffold(
drawer: drawer,
appBar: new AppBar(
title: new Text('Booze Up'),
),
body: new Column(children: <Widget>[
new ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 4,
itemBuilder: (BuildContext context, int index) {
return new Column(children: <Widget>[
new Container(
child: new Flexible(
child: new FlatButton(
child: new Image.asset('images/party.jpg',
width: width, height: width),
onPressed: buildlist('button' + index.toString()),
)),
width: width,
height: width,
)
]);
},
),
new Expanded(
child: new ListView(
padding: new EdgeInsets.fromLTRB(10.0, 10.0, 0.0, 10.0),
children: items,
scrollDirection: Axis.vertical,
)),
]),
floatingActionButton: new FloatingActionButton(
onPressed: null,
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class Refreshments {
String name;
int price;
Refreshments(this.name, this.price);
}
class ItemsList extends StatelessWidget {
final Refreshments refreshments;
ItemsList(this.refreshments);
@override
Widget build(BuildContext context) {
return new ListTile(
onTap: null,
title: new Text(refreshments.name),
);
}
}
Ich habe zwei Fehler:
1] Das horizontale Ansichtsfenster erhielt eine unbegrenzte Höhe. Einem horizontalen Ansichtsfenster wurde ein unbegrenzter vertikaler Raum zum Erweitern eingeräumt.
2] setState () oder markNeedsBuild, die während des Builds aufgerufen wurden Ein vertikaler Renderflex, der um 99488 Pixel übergelaufen ist.
Bitte helfen Sie mir dabei. Ich erstelle diese App, bei der auf jedem Bild eine Liste unten angezeigt wird. Die Bilder befinden sich in einer Reihe und die Liste sollte unter der Reihe angezeigt werden.
Vielen Dank.
In meinem Fall habe ich die setState-Methode aufgerufen, bevor die Build-Methode den Prozess zum Erstellen von Widgets abgeschlossen hat.
Dieser Fehler kann auftreten, wenn Sie vor Abschluss der Erstellungsmethode und in vielen anderen Fällen eine Snackleiste oder einen Warndialog anzeigen. Verwenden Sie in einer solchen Situation die folgende Rückruffunktion.
WidgetsBinding.instance.addPostFrameCallback((_){ // Add Your Code here. });
oder Sie können auch SchedulerBinding verwenden, das dasselbe tut.
SchedulerBinding.instance.addPostFrameCallback((_) { // add your code here. Navigator.push( context, new MaterialPageRoute( builder: (context) => NextPage())); });
quelle
MaterialPageRoute
in einemFutureBuilder
(Anmeldeerfolgsbildschirm) aufgetreten .Navigator.of(context).popUntil
methodDein Code
onPressed: buildlist('button'+index.toString()),
führt
buildlist()
das Ergebnis aus und übergibt es anonPressed
, aber das ist nicht das gewünschte Verhalten.Es sollte sein
onPressed: () => buildlist('button'+index.toString()),
Auf diese Weise wird eine Funktion (Schließung) übergeben
onPressed
, die bei Ausführung aufgerufen wirdbuildlist()
quelle
Ich habe den Status auch während des Builds festgelegt, also habe ich ihn auf das nächste Häkchen verschoben und es hat funktioniert.
vorher
Neu
Future.delayed(Duration.zero, () async { myFunction(); });
quelle
Ich habe diesen Fehler aufgrund eines ziemlich dummen Fehlers erhalten, aber vielleicht ist jemand hier, weil er genau das Gleiche getan hat ...
In meinem Code habe ich zwei Klassen. Eine Klasse (B) ist nur da, um mir ein spezielles Widget mit einer onTap-Funktion zu erstellen. Die Funktion, die durch das Tippen des Benutzers ausgelöst werden sollte, befand sich in der anderen Klasse (A). Also habe ich versucht, die Funktion der Klasse A an den Konstruktor der Klasse B zu übergeben, damit ich sie dem onTap zuweisen kann.
Leider habe ich die Funktionen, anstatt sie zu übergeben, aufgerufen. So sah es aus:
Offensichtlich ist dies der richtige Weg:
Dies löste meine Fehlermeldung. Der Fehler ist sinnvoll, da myFunction die Instanz der Klasse B ausführen musste und mein Build daher zuerst abgeschlossen werden musste (beim Aufrufen meiner Funktion wird eine Snackbar angezeigt).
Hoffe das hilft jemandem eines Tages!
quelle
Das Problem dabei
WidgetsBinding.instance.addPostFrameCallback
ist, dass es keine umfassende Lösung ist.Gemäß dem Vertrag von addPostFrameCallback -
Diese letzte Zeile klingt für mich wie ein Deal-Breaker.
Diese Methode ist nicht für den Fall geeignet, dass kein "aktueller Rahmen" vorhanden ist und der Flattermotor im Leerlauf läuft. Natürlich, in diesem Fall kann man aufrufen
setState()
direkt, aber auch hier, dass nicht wird immer Arbeit - manchmal gibt es einfach ist ein aktueller Rahmen.Zum Glück
SchedulerBinding
gibt es auch eine Lösung für diese kleine Warze - SchedulerPhaseBauen wir eine bessere
setState
, die sich nicht beschwert.(
endOfFrame
macht im Grunde das Gleiche wieaddPostFrameCallback
, außer dass es versucht, einen neuen Frame zu planenSchedulerPhase.idle
, und es verwendet async-await anstelle von Rückrufen)Future<bool> rebuild() async { if (!mounted) return false; // if there's a current frame, if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle) { // wait for the end of that frame. await SchedulerBinding.instance.endOfFrame; if (!mounted) return false; } setState(() {}); return true; }
Dies sorgt auch für schönere Kontrollflüsse, die offen gesagt einfach funktionieren .
await someTask(); if (!await rebuild()) return; await someOtherTask();
quelle