如何在HookWidget中使用Flutter State Restoration
如何将RestorationMixin与HookWidget配合实现Flutter状态恢复
1. 先启用全局状态恢复
在MaterialApp(或CupertinoApp)中设置全局恢复ID,这是状态恢复的基础:
MaterialApp( restorationScopeId: 'my_app', home: MyHookRestorationPage(), )
2. 用StatefulHookWidget + RestorationMixin实现
普通HookWidget没有State对象,无法直接混入RestorationMixin,可以借助flutter_hooks提供的StatefulHookWidget,它的State类既能混入RestorationMixin,又能正常使用hooks:
示例代码
import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; class MyHookRestorationPage extends StatefulHookWidget { const MyHookRestorationPage({super.key}); @override State<MyHookRestorationPage> createState() => _MyHookRestorationPageState(); } class _MyHookRestorationPageState extends State<MyHookRestorationPage> with RestorationMixin { // 定义可恢复的变量 final RestorableInt _counter = RestorableInt(0); // 当前页面的恢复ID @override String get restorationId => 'counter_page'; @override void restoreState(RestorationBucket? oldBucket, bool initialRestore) { // 注册可恢复变量到恢复桶 registerForRestoration(_counter, 'counter_value'); } @override void dispose() { // 释放Restorable变量 _counter.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // 正常使用hooks处理逻辑 final incrementCallback = useCallback(() { setState(() { _counter.value += 1; }); }, []); return Scaffold( appBar: AppBar(title: const Text('Hook + Restoration')), body: Center( child: Text('当前计数: ${_counter.value}'), ), floatingActionButton: FloatingActionButton( onPressed: incrementCallback, child: const Icon(Icons.add), ), ); } }
3. 纯HookWidget方案(无需Mixin)
如果不想用StatefulHookWidget,也可以在普通HookWidget中结合RestorationScope和useRestoration hook实现状态恢复,更贴合无状态组件的特性:
示例代码
import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; class MyPureHookRestorationPage extends HookWidget { const MyPureHookRestorationPage({super.key}); @override Widget build(BuildContext context) { // 创建可恢复的计数变量 final counter = useRestoration<int>( initialValue: 0, restorationId: 'pure_hook_counter', ); // 用hooks处理点击逻辑 final increment = useCallback(() { counter.value += 1; }, [counter]); return RestorationScope( // 给当前页面设置唯一恢复ID restorationId: 'pure_hook_page', child: Scaffold( appBar: AppBar(title: const Text('纯Hook + 状态恢复')), body: Center(child: Text('计数: ${counter.value}')), floatingActionButton: FloatingActionButton( onPressed: increment, child: const Icon(Icons.add), ), ), ); } }
关键注意事项
- 所有可恢复变量必须注册到对应恢复桶,不管是用
RestorationMixin的registerForRestoration还是useRestorationhook。 - 每个
RestorationScope和可恢复变量的restorationId必须唯一,避免冲突。 - 自定义复杂数据类型时,可以继承
RestorableProperty实现自定义可恢复类。
内容的提问来源于stack exchange,提问作者Shahbaz Hashmi
相关产品推荐
相关产品推荐

