Flutter Stateful Widget重新创建状态

我正在开发一个扑动的应用程序,并认识到状态管理的意外行为.我创建了一个示例应用程序来重现行为,您可以在下面找到代码和日志输出.

该应用程序包含一个简单的ListView,其中包含10个有状态容器(文本装饰).
当我向下滚动时,每个容器及其容器状态将按预期创建一次.当我再次向上滚动时,Flutter会为显示屏上再次出现的每个容器小部件重新创建每个状态(但不是容器小部件).
我希望颤振会在没有重新创建整个状态对象的情况下检索先前的状态.
在这里做错了吗?

Sample App


示例代码

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key) {
    print("MyHomePage constructor");
  }

  @override
  _MyHomePageState createState() {
    print("createState");
    return _MyHomePageState();
  }
}

class _MyHomePageState extends State<MyHomePage> {
  _MyHomePageState() {
    print("_MyHomePageState contructor");
  }

  void initState() {
    super.initState();

    print("_MyHomePageState initState");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: ListView.builder(
          itemBuilder: (context,index) {
            return ContainerWidget(index,key: ValueKey(index));
          },itemCount: 10,));
  }
}

class ContainerWidget extends StatefulWidget {
  int index;

  ContainerWidget(this.index,{key}) : super(key: key) {
    print("ContainerWidget constructor for index $index");
  }

  @override
  State<StatefulWidget> createState() {
    print("ContainerWidget createState for index $index");
    return _ContainerState();
  }
}

class _ContainerState extends State<ContainerWidget> {
  _ContainerState() {
    print("_ContainerState constructor");
  }

  void initState() {
    super.initState();

    print("_ContainerState initState for index ${widget.index}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text("Index: ${widget.index}"),),height: 200,decoration: Boxdecoration(
        border: Border(
          bottom: BorderSide(color: Colors.green),);
  }
}

对数输出

I/Flutter (22400): createState
I/Flutter (22400): _MyHomePageState contructor
I/Flutter (22400): _MyHomePageState initState
I/Flutter (22400): ContainerWidget constructor for index 0
I/Flutter (22400): ContainerWidget createState for index 0
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 0
I/Flutter (22400): ContainerWidget constructor for index 1
I/Flutter (22400): ContainerWidget createState for index 1
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 1
I/Flutter (22400): ContainerWidget constructor for index 2
I/Flutter (22400): ContainerWidget createState for index 2
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 2
I/Flutter (22400): ContainerWidget constructor for index 3
I/Flutter (22400): ContainerWidget createState for index 3
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 3
I/Flutter (22400): ContainerWidget constructor for index 4
I/Flutter (22400): ContainerWidget createState for index 4
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 4
I/Flutter (22400): ContainerWidget constructor for index 5
I/Flutter (22400): ContainerWidget createState for index 5
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 5
I/Flutter (22400): ContainerWidget createState for index 1
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 1
I/Flutter (22400): ContainerWidget createState for index 0
I/Flutter (22400): _ContainerState constructor
I/Flutter (22400): _ContainerState initState for index 0

解决方法

这是预期的,因为这些项目在离开屏幕时会被卸载.

如果你不想那样,你会想要使用我们称之为“保持活力”的东西.
你可以通过在你的State类中添加一个mixin来实现:

class _MyHomePageState extends State<MyHomePage> with AutomaticKeepAliveClientMixin {

  bool get wantKeepAlive => true;


  // ...
 }

相关文章

这篇文章主要讲解了“FlutterComponent动画的显和隐怎么实现...
这篇文章主要讲解了“flutter微信聊天输入框功能如何实现”,...
本篇内容介绍了“Flutter之Navigator的高级用法有哪些”的有...
这篇文章主要介绍“Flutter怎么使用Android原生播放器”,在...
Flutter开发的android端如何修改APP名称,logo,版本号,具体...
Flutter路由管理初识路由概念一.路由管理1.1.Route1.2.Mater...