在构建期间调用 setState()或 markNeedsBuild

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

全密码

我有两个错误:

水平视图被赋予无限高度。 一个水平的视窗被给予了无限量的垂直空间来扩展。

2] setState ()或 markNeedsBuild 在构建期间调用 垂直的 renderflex 溢出了99488个像素。

请帮帮我。我创建这个应用程序,在每个图像点击一个列表应该显示如下。图像将在一行中,列表应显示在该行的下方。

谢谢你。

207280 次浏览

你的代码

onPressed: buildlist('button'+index.toString()),

执行buildlist()并将结果传递给onPressed,但这不是期望的行为。

应该是这样

onPressed: () => buildlist('button'+index.toString()),

这样,函数(闭包)被传递给onPressed,在执行时调用buildlist()

在我的例子中,我在build方法完成构建小部件的过程之前调用了setState方法。

如果你在build方法完成之前显示snackBaralertDialog,以及在许多其他情况下,你可能会面临这个错误。因此,在这种情况下,你应该使用回调函数,如下所示:

WidgetsBinding.instance.addPostFrameCallback((_){


// Add Your Code here.


});

或者你也可以使用SchedulerBinding,它做同样的事情:

SchedulerBinding.instance.addPostFrameCallback((_) {


// add your code here.


Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => NextPage()));
});

我也在构建期间设置了状态,所以,我将它推迟到下一个滴答,它工作了。

以前

myFunction()

Future.delayed(Duration.zero, () async {
myFunction();
});

我收到这个错误,由于一个相当愚蠢的错误,但也许有人在这里,因为他做了完全相同的事情…

在我的代码中我有两个类。一个类(B)只是为我创建一个带有onTap函数的特殊小部件。应该由用户tap触发的函数是在另一个类(A)。所以我试图将类A的函数传递给类B的构造函数,这样我就可以将它分配给onTap。

不幸的是,我没有传递函数,而是调用了它们。 这是它看起来的样子:

ClassB classBInstance = ClassB(...,myFunction());

显然,这是正确的方法:

ClassB classBInstance = classB(...,myFunction);
这解决了我的错误消息。 这个错误是有意义的,因为为了让myFunction工作类B的实例,所以我的构建必须先完成(我在调用我的函数时显示了一个零食条)

希望有一天这能帮助到别人!

WidgetsBinding.instance.addPostFrameCallback的问题是,它不是一个包罗万象的解决方案。

根据合同addPostFrameCallback -

为这个帧的结束安排一个回调。 […] 这个回调在帧期间运行,就在持久帧之后 回调函数[…]。如果一个帧正在进行,而帧后回调还没有 尚未执行,则仍然执行已注册的回调 在画框中。否则执行注册的回调 在下一帧中。

对我来说,最后这句话听起来像是一场失败。

此方法不适用于处理没有“当前帧”且颤振发动机处于空闲状态的情况。当然,在这种情况下,可以直接调用setState(),但同样,这不会总是工作-有时只有当前帧。


值得庆幸的是,在SchedulerBinding中,也存在解决这个小疣的方法——SchedulerPhase

让我们构建一个更好的setState,一个没有抱怨的setState

(endOfFrameaddPostFrameCallback做的事情基本相同,除了它尝试在SchedulerPhase.idle调度一个新帧,并且它使用async-await而不是回调)

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

这也使得更好的控制流,坦率地说,只是工作

await someTask();


if (!await rebuild()) return;


await someOtherTask();

当你使用onWillpop方法返回时,会出现这种类型的错误

onWillPop: onBackPressedWillPopeback());

用这个替换

onWillPop: () => onBackPressedWillPopeback());

我相信你的错误会得到解决的。如果任何时候有其他问题问我…

在我的例子中,我使用的是GetX和滑动条。对于我的滑块,我直接使用了Rx变量而不是实际值。

我的代码。

RxDouble sliderValue = 1.0.obs;


MySlider(
value: this.sliderValue
)

我将代码更改为:

MySlider(
value: this.sliderValue.value
)

现在错误消失了。

只要删除花括号{}从onTap()的情况下InkWell和onPressed()的情况下GestureDetector或按钮等。