iOS开发Flutter探索-State状态保存(10)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发Flutter探索-State状态保存(10)相关的知识,希望对你有一定的参考价值。

参考技术A 有时候我们不希望某个页面每次打开时都重新加载,比如就我们之前的Tabbar结构的页面,每当我们在切换Tab的时候都会执行 void initState() ,这就意味着页面每次都会重新渲染,之所以这样就是因为我们的 State 状态没有保存,如下图所示:
[没有状态保存效果图]

给当前 State 类添加一个扩展(这里就用扩展这个词吧,其实类似于ios下的 Category ),一个系统的扩展类 AutomaticKeepAliveClientMixin ,并重写 wantKeepAlive 方法,让一个普通的 State 类,具有保存状态的能力。
在Dart语法中通过使用 with 关键字来添加扩展:

bool get wantKeepAlive => true; 之后,当前 State 就具备保存能力了,也就意味着重复切换Tab后, void initState() 就不会重复执行了(由原来的 viewWillAppear() 变成了 viewDidLoad() )。

按照上面方式修改后,发现切换Tab后 void initState() 依然重复执行了,这是为什么呐?这里我们看下我们之前 root_page.dart 里面是如何配置我们的tabbar结构的:

这里我们是通过一个 _viewControllers 的List,把4个子页面放在了里面,全局有一个 _currentIndex ,当 onTap 回调后后,更新 _currentIndex 的值,执行 setState () 后, body 对应的 widget 页面发生改变。而问题也就出在这里,当 body 部分发生改变时,根据Flutter的底层渲染逻辑,这里会移除掉之前的 Widget ,并重新创建新的 Widget ,我们之前在 _viewControllers 放的子页面,并不像iOS下是一个实例对象,存在就直接拿来使用。在Flutter 中 setState () 后界面会被重新绘制,而 body 部分只知道我要渲染一个什么样的 widget ,而该类型的 widget 每次都是会重新创建,这也就意味着我们在Tab切换时,每次都是重新创建,所以每次都执行了 initState() 。
显然我们现在的方式是不合理的,那在Flutter中如何管理这样的子页面,而避免重复渲染呐?
这就要用到一个新的部件了: PageView() ,内部的2个关键属性:

子页面切换通过 _controller.jumpToPage(index); 来实现。
这样子页面也就不会重新创建渲染了,我们的状态保存也就能正常实现了。

学习是一个循序渐进的过程,我们总是在踩坑中不断的前行,把坑填平了也就意味着我们在这个新的东西面前立了足,就可能进行更多为什么的探索了。

以上是关于iOS开发Flutter探索-State状态保存(10)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 组件的生命周期State 管理及局部重绘 | 开发者说·DTalk

Flutter State Management状态管理全面分析

Flutter BLoC 库:将 TextEditingController 对象保存在哪里:在 State、BLoC / Cubit 类中还是在小部件中?

Flutter - Stateful(有状态) 和 stateless(无状态) widgets

Flutter Stateful Widget 重新创建 State

Flutter包大小治理上的探索与实践