Flutter 提供程序在导航到另一个屏幕时失去价值

Flutter provider loosing value when navigating to another screen

我是 Flutterprovider package 的新手,所以任何帮助都会很好,所以我的 main.dart 文件如下所示:

 void main() => runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData.light(),
        home: ChangeNotifierProvider(
          create: (_) => InterestingMomentProvider(),
          child: Home(),
        ),
     ),
  );

这构建了我的 Home 小部件,我不会 post 全部,因为它非常大,但是,我点击一个按钮,它会将一个字符串传递给提供者 class 并将其添加到概述如下的列表中:

import 'package:flutter/widgets.dart';

class InterestingMomentProvider extends ChangeNotifier {

  List<String> _moments = [];

  List<String> get moments => _moments;

  void addMoment(String time){
    _moments.add(time);
  }

  int momentsTotal(){
    return _moments.length;
  }

}

在 addMoment 方法上添加断点我可以确认 _moments 包含所有字符串。

然后我按一个按钮导航到另一个屏幕,导航代码如下:

Navigator.push(context, MaterialPageRoute(builder: (context) => MomentsRecorded()),);

MomentsRecorded插件如下:

class MomentsRecorded extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Moments'),
        centerTitle: true,        
      ),
      body: Center(
        child: MomentsList()
        ),
    );
  }
}

第一个错误是:

Could not find the correct Provider<InterestingMomentProvider> above this Consumer<InterestingMomentProvider> Widget

To fix, please:

  * Ensure the Provider<InterestingMomentProvider> is an ancestor to this Consumer<InterestingMomentProvider> Widget
  * Provide types to Provider<InterestingMomentProvider>
  * Provide types to Consumer<InterestingMomentProvider>
  * Provide types to Provider.of<InterestingMomentProvider>()
  * Always use package imports. Ex: `import 'package:my_app/my_code.dart';
  * Ensure the correct `context` is being used.

然后我将正文调整为如下所示,错误消失了:

 body: Center(
        child: ChangeNotifierProvider(
          create: (_) => InterestingMomentProvider(),
          child: MomentsList())
        ),

但是在 MomentLists 小部件中,我尝试循环遍历来自提供程序 class 的时刻列表,但是当调试 _moments 为 0 时?

时刻列表小部件:

class MomentsList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<InterestingMomentProvider>(
      builder: (context, momentData, child){
        return momentData.momentsTotal() > 0 ? ListView.builder(
          itemCount: momentData.momentsTotal(),
          itemBuilder: (BuildContext context, int index) {
            final moment = momentData.moments[index];
            return ListTile(
                title: Text(moment),
            );
          }
        ) : Center(child: Text('no moments recorded'),);
      }

    );
  }
}

有人可以解释为什么会这样吗?

发生这种情况,因为您的提供程序是在 MaterialApphome 属性 中定义的,因此当您更改路由时,提供程序也会被删除。

解决方案:将提供程序移动到 MaterialApp 上方,如下所示:

 void main() => runApp(
  ChangeNotifierProvider(
    create: (_) => InterestingMomentProvider(),
    child: MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.light(),
      home: Home()
    ),
  ),
);

如果你担心这不对 - checkout the docs, they doing the same