Flutter 状态管理 实践记录

1. 背景

Flutter里面最重要的应该就是:状态管理 刚开始做的一个问题,StatefulWidget的状态应该被谁管理?Widget本身?父Widget?还是其他对象?以下是管理状态的最常见的方法:

  • Widget管理自己的状态。
  • 父Widget管理子Widget状态。
  • 混合管理(父Widget和子Widget都管理状态)。

举个例子:比如 CheckBox 里面的数据到底是给谁管理比较方便

官方的原则是:

  • 如果状态是用户数据,如复选框的选中状态、滑块的位置,则该状态最好由父Widget管理。
  • 如果状态是有关界面外观效果的,例如颜色、动画,那么状态最好由Widget本身来管理。
  • 如果某一个状态是不同Widget共享的则最好由它们共同的父Widget管理

因此,如果是Checkbox,那么 选中状态应该是让外部来管理,如果是颜色,样式等应该是让 widget本身管理。。

2. 遇到的问题

看起来挺美好的,但是在开发过程中还是可能遇到问题。

比如: 在开发相册的时候,实现了分页加载列表 的widget,当下滑列表位置 > 0.7* 列表总长度时候,加载下一页。而且这个widget,可以根据外部传进来的文件夹路径,重新初始化数据。
而且控件直接的 选中数据是同一份。

UI类似:

 按上面的原则,应该是把 widget设置为 statelessWidget, 然后数据交由外部管理。 但是这个例子比较特殊,如果按上面的原则来实现会变的复杂。

因为:控件是会根据内部的数据 currentPage来加载下一页。 但是外部又要能重新设置 currentPage来重置。

因此 是内部和外部都会改变 currentPage的数据状态。 后面是采用了 混合 管理方式。

特别要注意的时候,混合管理的时候,要记得在: didUpdateWidget,里面重新设置数据;

  @override
  void didUpdateWidget(PhotoGrid oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.pathEntity.id != oldWidget.pathEntity.id) {
      resetData();
      loadMore(widget.pathEntity);
    }
  }

  void loadMore(AssetPathEntity pathEntity) async {
    loading = true;
    List<AssetEntity> media =
        await pathEntity.getAssetListPaged(currentPage, 60);

    if (media.isEmpty) {
      isEnd = true;
    } else {
      setState(() {
        dataList.addAll(media);
        currentPage++;
        loading = false;
      });
    }
  }


3. Widget的生命周期

这个图很关键,可以看到,每次重新buildwidget的时候都会 调用 didUpdateWidget。因此新的数据,可以再此赋值

生命周期
 

猜你喜欢

转载自blog.csdn.net/jdsjlzx/article/details/126792073