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

Flutter页面状态保存:非Navigator.pop返回时保留变量值

Hey there! The issue you're facing is that when you use Navigator.pushNamed(context, '/') from Page01, you're actually adding a new instance of MyHomePage to the navigation stack instead of returning to the original one. That's why your _counter resets—you're looking at a completely fresh page widget, not the one you had before.

The AutomaticKeepAliveClientMixin works great for keeping state when widgets are kept in the widget tree (like pages in a PageView that aren't disposed when you switch tabs), but it doesn't help here because the original MyHomePage is still in the stack, you're just not going back to it.

Solution 1: Use Navigator.pop() (the simplest fix)

Even though you mentioned not wanting to use pop, this is Flutter's intended way to return to the previous page in the navigation stack. In your Page01's onTap, replace Navigator.pushNamed(context, '/') with:

Navigator.pop(context);

This will remove Page01 from the stack and reveal the original MyHomePage with its state intact—no extra setup needed.

Solution 2: Keep pages alive with IndexedStack (if you need persistent pages without popping)

If you really need to switch between pages without popping (like a tab bar-style setup), you can use an IndexedStack to manage your pages. This widget keeps all its children in the widget tree, so their state is preserved even when they're not visible.

Here's how to adjust your code:

  1. Modify MyApp to use a stateful widget that tracks the current page index:
import 'package:flutter/material.dart';
import 'Page01.dart';
import 'MyHomePage.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 _currentIndex = 0;
  late final List<Widget> _pages;

  @override
  void initState() {
    super.initState();
    _pages = [
      MyHomePage(
        title: 'Flutter Demo Home Page',
        onSwitchToPage01: () => _switchPage(1),
      ),
      Page01(
        onSwitchToHome: () => _switchPage(0),
      ),
    ];
  }

  void _switchPage(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: IndexedStack(
          index: _currentIndex,
          children: _pages,
        ),
      ),
    );
  }
}
  1. Update MyHomePage to accept a callback for page switching:
import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({
    super.key,
    required this.title,
    required this.onSwitchToPage01,
  });

  final String title;
  final VoidCallback onSwitchToPage01;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with AutomaticKeepAliveClientMixin<MyHomePage> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            const SizedBox(height: 50),
            InkWell(
              onTap: widget.onSwitchToPage01,
              child: Container(
                height: 50,
                width: 100,
                color: Colors.red,
                child: const Center(child: Text('change page')),
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}
  1. Update Page01 to accept a callback for returning home:
import 'package:flutter/material.dart';

class Page01 extends StatefulWidget {
  const Page01({
    Key? key,
    required this.onSwitchToHome,
  }) : super(key: key);

  final VoidCallback onSwitchToHome;

  @override
  State<Page01> createState() => _Page01State();
}

class _Page01State extends State<Page01> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: InkWell(
          onTap: widget.onSwitchToHome,
          child: Container(
            height: 50,
            width: 100,
            color: Colors.red,
            child: const Center(child: Text('change page')),
          ),
        ),
      ),
    );
  }
}

With this setup, both pages are kept alive in the IndexedStack, so your _counter value will stay intact when switching between them.

Solution 3: Use state management (for more complex apps)

If your app is going to grow, moving state like _counter to an app-level state manager (like Provider, Riverpod, or GetX) is a scalable solution. This way, the state isn't tied to the widget's lifecycle—even if the widget is rebuilt, it will read the latest state from the manager.

For example, using Provider:

  1. Create a state class:
import 'package:flutter/foundation.dart';

class CounterState with ChangeNotifier {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners();
  }
}
  1. Provide it in your MyApp:
ChangeNotifierProvider(
  create: (context) => CounterState(),
  child: MaterialApp(...),
)
  1. Use it in MyHomePage:
final counterState = Provider.of<CounterState>(context);

// Replace _counter with counterState.counter
Text(
  '${counterState.counter}',
  style: Theme.of(context).textTheme.headline4,
),

// Replace _incrementCounter with:
void _incrementCounter() {
  counterState.increment();
}

Now, no matter how you navigate between pages, the counter state will be preserved because it's stored outside the widget tree.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:45:29