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

如何保持Flutter抽屉(Drawer)子Widget的状态不丢失

解决Drawer中Stateful Widget状态重置的问题

问题原因

每次关闭并重新打开Drawer时,Flutter会销毁原有的Drawer及其子组件实例,重新创建新的实例,这就导致Counter的State被重新初始化,计数随之重置。

解决方案

方法一:状态提升(最直接的轻量方案)

把Counter的计数状态转移到Drawer的父组件(MyApp)中,让父组件负责维护状态,Drawer仅作为状态的展示和操作载体。即使Drawer重建,状态也会保留在父组件里。

修改后的完整代码:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _count = 0;

  void _incrementCounter() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        drawer: Drawer(
          child: Counter(
            count: _count,
            onIncrement: _incrementCounter,
          ),
        ),
        appBar: AppBar(),
        body: Container(),
      ),
    );
  }
}

// 将Counter改为StatelessWidget,状态由父组件传入和管理
class Counter extends StatelessWidget {
  final int count;
  final VoidCallback onIncrement;

  const Counter({
    super.key,
    required this.count,
    required this.onIncrement,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(count.toString()),
        ElevatedButton(
          onPressed: onIncrement,
          child: const Text('Increment Counter'),
        )
      ],
    );
  }
}

方法二:使用GlobalKey保留State

通过GlobalKey关联Counter的State,确保Drawer重建时,Counter的State不会被销毁,而是复用之前的实例。

修改后的完整代码:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // 创建GlobalKey来绑定Counter的State
  final GlobalKey<_CounterState> _counterKey = GlobalKey<_CounterState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        drawer: Drawer(
          // 给Counter传入同一个GlobalKey,确保State复用
          child: Counter(key: _counterKey),
        ),
        appBar: AppBar(),
        body: Container(),
      ),
    );
  }
}

class Counter extends StatefulWidget {
  const Counter({super.key});

  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(_count.toString()),
        ElevatedButton(
          onPressed: _increment,
          child: const Text('Increment Counter'),
        )
      ],
    );
  }
}

方法三:使用状态管理库(适合复杂项目)

如果项目规模较大、状态需要在多个组件间共享,可以用Provider、Riverpod等状态管理库,将计数状态抽离为全局可访问的状态,彻底摆脱组件重建的影响。

内容的提问来源于stack exchange,提问作者Joel Castro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:10:55