Flutter 2不使用StatefulWidget如何实现状态恢复?
Flutter无StatefulWidget场景下的状态恢复实现方案
你不需要为了状态恢复改造业务层的StatelessWidget,也不需要处理多组件共享状态的恢复冲突,以下是两种可直接落地的实现方案:
方案1:根节点统一托管恢复逻辑
仅在应用根节点增加一个唯一的StatefulWidget作为恢复锚点,所有状态恢复逻辑都收敛在这个节点,和下层业务完全解耦:
- 给你的共享ChangeNotifier实现序列化/反序列化方法,比如
toJson()和fromJson(Map data),导出需要恢复的核心状态字段 - 实现根级恢复托管组件,代码示例如下:
class AppRestorationHost extends StatefulWidget { final Widget child; const AppRestorationHost({super.key, required this.child}); @override State<AppRestorationHost> createState() => _AppRestorationHostState(); } class _AppRestorationHostState extends State<AppRestorationHost> with RestorationMixin { final RestorableString _serializedAppState = RestorableString(''); @override String? get restorationId => 'app_root_restoration'; @override void restoreState(RestorationBucket? oldBucket, bool initialRestore) { registerForRestoration(_serializedAppState, 'global_app_state'); // 恢复状态到全局共享的ChangeNotifier实例 if (_serializedAppState.value.isNotEmpty) { final restoredState = AppState.fromJson(jsonDecode(_serializedAppState.value)); // 替换为你自己的状态更新逻辑,比如Provider更新/全局单例赋值 globalAppNotifier.updateState(restoredState); } // 监听状态变化同步更新恢复缓存 globalAppNotifier.addListener(() { _serializedAppState.value = jsonEncode(globalAppNotifier.toJson()); }); } @override Widget build(BuildContext context) => widget.child; }
- 在应用入口用托管组件包裹你的
MaterialApp即可,注意给MaterialApp配置restorationScopeId:
void main() { runApp( AppRestorationHost( child: MaterialApp( restorationScopeId: 'app_main', // 其余原有配置不变 ), ) ); }
方案2:封装可恢复的ChangeNotifier基类
如果不想额外加根节点组件,也可以直接把恢复逻辑封装到状态基类中,业务层无感知:
- 自定义
RestorableChangeNotifier基类,继承自ChangeNotifier,内置序列化、状态同步、系统恢复API绑定逻辑 - 基类对外暴露
Map<String, dynamic> toRestorableData()和void restoreFromData(Map<String, dynamic> data)两个抽象方法,业务状态类仅需要实现这两个方法就能自动获得状态恢复能力,不需要和任何业务Widget绑定
你之前看到的「状态恢复必须绑定StatefulWidget」是对API的使用场景误解,Flutter的恢复API仅要求存在一个持有
RestorationMixin的Widget作为恢复锚点,这个锚点完全可以是全局唯一的根节点,不需要侵入到业务页面层级。
内容的提问来源于stack exchange,提问作者VladH
相关产品推荐
相关产品推荐

