Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android didupdatewidget dosen';用setstate单击按钮后无法打印。它真正的作用是什么?_Android_Flutter_Dart_Widget - Fatal编程技术网

Android didupdatewidget dosen';用setstate单击按钮后无法打印。它真正的作用是什么?

Android didupdatewidget dosen';用setstate单击按钮后无法打印。它真正的作用是什么?,android,flutter,dart,widget,Android,Flutter,Dart,Widget,我正在学习颤振,didupdatewidget出现在教程中。我真的不知道它是干什么的。我制作了这样一个应用程序,它在单击按钮后将卡片添加到列中,但在更新卡片列表(products类)后,didupdatewidget不会打印任何内容 导入“包装:颤振/材料.省道”; 导入“/products.dart”; 类ProductsManager扩展StatefulWidget{ 最终管柱起动产品; ProductsManager(此.startingproduct); @凌驾 State create

我正在学习颤振,didupdatewidget出现在教程中。我真的不知道它是干什么的。我制作了这样一个应用程序,它在单击按钮后将卡片添加到列中,但在更新卡片列表(products类)后,didupdatewidget不会打印任何内容

导入“包装:颤振/材料.省道”;
导入“/products.dart”;
类ProductsManager扩展StatefulWidget{
最终管柱起动产品;
ProductsManager(此.startingproduct);
@凌驾
State createState()=>ProductsManager状态();
}
类ProductsManager状态扩展状态{
列表_产品=[];
@凌驾
void initState(){
super.initState();
_products.add(widget.startingproduct);
打印(“初始状态被称为”);
}
@凌驾
void didUpdateWidget(ProductsManager oldWidget){
打印(“更新小部件”);
super.didUpdateWidget(oldWidget);
}
@凌驾
小部件构建(构建上下文){
打印(“全州PM构建”);
返回列(
儿童:[
容器(
边距:所有边缘集(9.0),
孩子:升起按钮(
颜色:主题。背景。原色,
子项:文本(“数据”),
已按下:(){
设置状态(){
打印(称为“设置状态”);
_添加(“高级食品检测仪”);
});
},
),
),
产品(_产品)
],
);
}
}

didupdatewidget如何显示应用程序已更新???

据我所知,在一个状态中调用“setState()”不会使该状态的didupdatewidget()被调用

但是,如果“build()”方法中此状态返回的小部件是StatefulWidget(或者如果从这一点开始树中有任何StatefulWidget),则将调用这些StatefulWidget状态中的“didUpdateWidget()”

为了理解原因,我们可以在framework.dart中查看Flatter的源代码,下面是在状态中调用“setState()”时代码流的大致摘要:

  • stateA(比如)调用“setState()”
  • 在“setState()”中,它调用“_element.markNeedsBuild()”,这会将“_element”添加到脏元素列表中,这些脏元素稍后将由flatter重新构建(“_element”只是StateA绑定到的元素对象,为了方便起见,我们将其命名为elementA)
  • 在下一帧中,flatter将遍历脏元素列表,对于每个元素“element”,flatter调用element.rebuild(),因此将在循环中调用elementA.rebuild()
  • 在elementA.rebuild()中,它最终调用“build=stateA.build()”,然后调用“updateChild(_child,builded)”(其中_child是elementA树下的下一个元素,此“build”小部件绑定到该元素)
  • updateChild(_child,Build)将小部件“Build”设置为元素“_child”的绑定小部件,因此这里是“元素配置更改”发生的地方,因此在元素“_child”内部调用“didUpdateWidget()”(如果它是StatefulElement)
  • 对于“didUpdateWidget()”,flatter文档说它“在小部件配置更改时调用” 关键思想是,stateA中的“setState()”不会重建widgetA,而是重建stateA返回的小部件。因此,“配置更改”发生在返回的小部件上,而widgetA保持不变

    import 'package:flutter/material.dart';
    import './products.dart';
    
    class ProductsManager extends StatefulWidget {
      final String startingproduct;
      ProductsManager(this.startingproduct);
      @override
      State<StatefulWidget> createState() => ProductsManagerState();
    }
    
    class ProductsManagerState extends State<ProductsManager> {
      List<String> _products = [];
    
      @override
      void initState() {
        super.initState();
        _products.add(widget.startingproduct);
        print("InitState called");
    }
    
      @override
      void didUpdateWidget(ProductsManager oldWidget) {
        print("Updated the widget");
        super.didUpdateWidget(oldWidget);
     }
    
      @override
      Widget build(BuildContext context) {
        print("build of statefull PM");
        return Column(
          children: <Widget>[
            Container(
              margin: EdgeInsets.all(9.0),
              child: RaisedButton(
                color: Theme.of(context).primaryColor,
                child: Text("data"),
                onPressed: () {
                  setState(() {
                    print("Setstate called ");
                    _products.add("Advanced Food Tester");
                  });
                },
              ),
            ),
            Products(_products)
          ],
        );
      }
    }