使用riverpod在flutter中导航到另一个屏幕时如何保留应用程序的状态

问题描述

大家好

我是使用 Riverpod 的新手,我有一个计数器应用程序,当点击 FAB 按钮时,它会将计数器增加 1。这在使用 Riverpod ChangeNotifierProvider 时效果很好。 我目前遇到的问题是当我点击另一个用户带到第二个屏幕的按钮时,在第二个屏幕中保留计数器的状态。

下面是我的代码

main.dart

import 'package:Flutter/material.dart';
import 'package:Flutter_riverpod/Flutter_riverpod.dart';
import 'package:Flutter_riverpod_app/counter.dart';
import 'package:Flutter_riverpod_app/second_screen.dart';

final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter());

void main() {
  runApp(ProviderScope(
    child: MyApp(),));
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',theme: ThemeData(
        primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: MyHomePage(title: 'Flutter Demo Home Page'),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key,this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Consumer(builder: (context,watch,_) {
          final count = watch(counterProvider);
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
              Text(
                'You have pushed the button this many times:',Text(
                '${count.count}',style: Theme.of(context).textTheme.headline4,FlatButton(
                  onpressed: () {
                    Navigator.push(
                        context,MaterialPageRoute(
                            builder: (BuildContext context) => SecondScreen()));
                  },child: Text('Go to second screen'))
            ],);
        }),floatingActionButton: FloatingActionButton(
        onpressed: () => context.read(counterProvider).updateCount(),tooltip: 'Increment',child: Icon(Icons.add),// This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

second_screen.dart

import 'package:Flutter/material.dart';
import 'package:Flutter_riverpod/Flutter_riverpod.dart';
import 'package:Flutter_riverpod_app/counter.dart';

final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter());

class SecondScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context,watch) {
    final counter = watch(counterProvider);
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Screen'),body: Center(
        child: Text('${counter.count}',style: TextStyle(fontSize: 30,);
  }
}

计数器.dart

import 'package:Flutter/foundation.dart';

class Counter extends ChangeNotifier {
  int count = 0;

  updateCount() {
    count++;
    notifyListeners();
  }
}

我真的不知道如何在第二个屏幕上获取计数器的状态,如果是提供程序包,我只需要在第二个屏幕上使用 Provider.of<counter>(context,listen: false).counter 就可以了显示计数器。

First screen

Second screen where the state isn't retained

解决方法

问题是您创建了两次 Provider。您只想创建一次并全局访问它。

从您的 SecondScreen 中删除 final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter());,而是从您的 FirstScreen 中导入 counterProvider,它会按照您的预期运行。