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),
);
}
}
我有两个错误:
1]水平视口被赋予无限高度。 水平视口被赋予了无限量的垂直空间,可以在其中展开。
2]在构建期间调用setState()或markNeedsBuild 一个垂直的renderflex溢出99488像素。
请帮帮我。我正在创建这个应用程序,在每个图像上单击列表应显示如下。图像将排成一行,列表应显示在行下方。
谢谢。
答案 0 :(得分:34)
您的代码
onPressed: buildlist('button'+index.toString()),
执行buildlist()
并将结果传递给onPressed
,但这不是理想的行为。
应该是
onPressed: () => buildlist('button'+index.toString()),
这样一个函数(闭包)传递给onPressed
,执行时调用buildlist()
答案 1 :(得分:25)
我还在构建过程中设置了状态,因此,我将其推迟到下一个刻度,然后它起作用了。
以前
myFunction()
新
Future.delayed(Duration.zero, () async {
myFunction();
});
答案 2 :(得分:2)
我已经重新创建了你要做的事情,只有两个Refreshment项目,你可能想要以更好的方式重构事物并处理布局,但为了简单起见,请尝试按照这个例子进行比较它是你想要实现的目标:
import "package:flutter/material.dart";
class LetsParty extends StatefulWidget {
@override
_LetsPartyState createState() => new _LetsPartyState();
}
class _LetsPartyState extends State<LetsParty> {
Image _partyImage = new Image.network(
"http://www.freshcardsgifts.co.uk/images/_lib/animal-party-greetings-card-3003237-0-1344698261000.jpg");
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
List<List> list = [
["Pina Colada",
"Bloody Mary",
"Strawberry Flush",
"Mango Diver",
"Peach Delight"
],
[
"Absolute",
"Smirnoff",
"White Mischief",
"Romanov",
"Blender's Pride"
]
];
List<String> visibleList = null;
@override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(title: new Text("Let's Party"),),
body: new ListView(
// shrinkWrap: true,
children: <Widget>[
new Container (
height: 150.0,
child: new ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 2, //add the length of your list here
itemBuilder: (BuildContext context, int index) {
return new Column(
children: <Widget>[
///Flexible let's your widget flex in the given space, dealing with the overflow you have
// new Flexible(child: new FlatButton(onPressed: ()=>print("You pressed Image No.$index"), child: _partyImage)),
new Flexible (child: new Container(
child: new FlatButton(onPressed: () {
scaffoldKey.currentState.showSnackBar(
new SnackBar(
content: new Text(
"You pressed Image No.$index")));
setState(() {
visibleList = list[index];
});
},
child: _partyImage),
width: 100.0,
height: 100.0
),),
//Exact width and height, consider adding Flexible as a parent to the Container
new Text("Text$index"),
],
);
})),
new Column(children: visibleList==null?new List():new List.generate(5, (int i) {
new ListTile(title: new Text(visibleList[i]),
onTap: () =>
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text("Your choise is ${visibleList[i]}"),)),
);
}))
],),);
}
}
答案 3 :(得分:1)
由于一个非常愚蠢的错误,我收到了此错误,但也许有人在这里是因为他做了完全相同的事情...
在我的代码中,我有两个类。一个类(B)在那里为我创建了一个带有onTap函数的特殊小部件。用户轻触应触发的功能在另一类(A)中。因此,我试图将A类的功能传递给B类的构造函数,以便可以将其分配给onTap。
不幸的是,与其传递函数,我没有调用它们。 看起来像这样:
ClassB classBInstance = ClassB(...,myFunction());
显然,这是正确的方法:
ClassB classBInstance = classB(...,myFunction);
这解决了我的错误消息。 该错误是有道理的,因为为了使myFunction能够运行类B的实例,因此我的构建必须首先完成(调用函数时,我会显示小吃板)。
希望这对某人有帮助!
答案 4 :(得分:0)
就我而言,我是在构建小部件的构建方法完成过程之前调用setState方法的。
如果在完成构建方法之前显示小吃店或警报对话框,并且在许多其他情况下,则可能会遇到此错误。因此在这种情况下,请使用下面的回调函数。
WidgetsBinding.instance.addPostFrameCallback((_){
// Add Your Code here.
});
答案 5 :(得分:0)
WidgetsBinding.instance.addPostFrameCallback
的问题在于,它不是一个全面的解决方案。
根据addPostFrameCallback的合同-
计划此帧结束时的回调。 [...] 此回调在持久帧之后的一个帧中运行 回调[...]。如果正在进行帧,并且没有帧后回调 已执行,然后仍执行已注册的回调 在框架中。 否则,将执行注册的回调 在下一帧。
最后一行对我来说听起来像是一个破坏交易的事情。
该方法无法处理没有“当前帧”且颤振引擎处于空闲状态的情况。当然,在那种情况下,人们可以直接调用setState()
,但是同样,它不会总是起作用-有时是当前框架。< / p>
值得庆幸的是,在SchedulerBinding
中,还存在针对这种小疣的解决方案-SchedulerPhase
让我们建立一个更好的setState
,这是不会抱怨的。
({endOfFrame
与addPostFrameCallback
基本上具有相同的功能,除了它尝试在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();
答案 6 :(得分:0)
当您使用 onWillpop 方法返回时,会出现此类错误
onWillPop: onBackPressedWillPopeback());
替换成这个
onWillPop: () => onBackPressedWillPopeback());
我相信你的错误会得到解决...如果有任何其他问题随时问我...