Как сохранить состояние приложения при переходе на другой экран во флаттере с помощью riverpod

Доброго времени суток ребята

Я новичок в использовании 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,),),
      ),
    );
  }
}

counter.dart

import 'package:flutter/foundation.dart';

class Counter extends ChangeNotifier {
  int count = 0;

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

Я действительно не знаю, как получить состояние счетчика на втором экране, если это был пакет поставщика, все, что мне нужно было сделать на втором экране, - это использовать Provider.of<counter>(context, listen: false).counter, и он отобразит счетчик. Первый  screen  Второй экран, состояние которого не сохраняется


person KelvinROLEX    schedule 22.04.2021    source источник


Ответы (1)


Проблема в том, что вы дважды создали Provider. Вам нужно создать его только один раз и получить к нему глобальный доступ.

Удалите final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter()); из вашего SecondScreen и вместо этого импортируйте counterProvider из вашего FirstScreen, и он будет вести себя так, как вы ожидаете.

person Alex Hartford    schedule 22.04.2021