You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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还是useRestoration hook。
  • 每个RestorationScope和可恢复变量的restorationId必须唯一,避免冲突。
  • 自定义复杂数据类型时,可以继承RestorableProperty实现自定义可恢复类。

内容的提问来源于stack exchange,提问作者Shahbaz Hashmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:15:14