首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在构建期间调用setState()或markNeedsBuild

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

Stack Overflow用户
提问于 2017-12-01 19:21:00
回答 4查看 128.6K关注 0票数 161
代码语言:javascript
复制
class MyHome extends StatefulWidget {
  @override
  State createState() => new MyHomePage2();
}

class MyHomePage2 extends State {
  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: [
      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: [
        new ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 4,
          itemBuilder: (BuildContext context, int index) {
            return new Column(children: [
              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),
    );
  }
}

由DartPad ;-)**](https://dartpad.dartlang.org/45ebdf271cf45e20a7ad5f5564742517)格式化的

我有两个错误:

1]水平视口被赋予无界高度。水平视口有无限的垂直空间可供扩展。

2]构建过程中调用的setState()或markNeedsBuild垂直renderflex溢出99488像素。

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

谢谢你。

EN

回答 4

Stack Overflow用户

发布于 2017-12-01 19:34:59

你的代码

代码语言:js
复制
onPressed: buildlist('button'+index.toString()),

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

它应该是

代码语言:js
复制
onPressed: () => buildlist('button'+index.toString()),

这样,一个函数(闭包)被传递给onPressed,当执行时,调用

buildlist()

票数 170
EN

Stack Overflow用户

发布于 2020-08-27 08:59:09

我还在构建期间设置了状态,因此,我将其推迟到下一个滴答,它起作用了。

之前

代码语言:js
复制
myFunction()

新的

代码语言:javascript
复制
Future.delayed(Duration.zero, () async {
  myFunction();
});
票数 73
EN

Stack Overflow用户

发布于 2020-11-06 01:22:55

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

根据…的合同addPostFrameCallback-

计划此帧末尾的回调。..此回调在帧期间运行,紧接在持久帧回调之后....如果某个帧正在进行中,并且尚未执行帧后回调,则在该帧期间仍会执行已注册的回调。

否则,注册的回调将在下一帧期间执行。

对我来说,最后一行听起来像是一个破坏交易的因素。

这个方法不能处理没有“当前帧”的情况,并且颤动引擎是空闲的。当然,在这种情况下,可以调用setState()直接,但再说一次,这不会始终工作-有时只是是当前帧。

谢天谢地,在SchedulerBinding,也有一个解决方案来解决这个小瘤-SchedulerPhase让我们构建一个更好的setState,一个不会抱怨的人。(endOfFrame基本上做的事情和addPostFrameCallback,除非它尝试在SchedulerPhase.idle,它使用async-await而不是回调)

代码语言:javascript
复制
Future 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;
}

这也有助于更好的控制流程,坦率地说,只管工作..。

代码语言:javascript
复制
await someTask();

if (!await rebuild()) return;

await someOtherTask();
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47592301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档