【问题标题】:flutter provider what is the difference with 'Context context' and 'context '颤振提供者与“上下文上下文”和“上下文”有什么区别
【发布时间】:2020-10-29 22:20:35
【问题描述】:
```
import 'package:a_class_flutter/provider/ac_score/ac_score_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';

class ACScoreView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ACScoreProvider(),
      builder: (context, child) {
        return Stack(
          children: <Widget>[
            _topMenu(context),
          ],
        );
      },
    );
  }
}
// Important!
Widget _topMenu(BuildContext context) {
  return GestureDetector(
    onTap: () {
      context.read<ACScoreProvider>().showTopMenueStatus();
    },
    child: Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.red,
      child: Stack(
        children: <Widget>[
          Positioned(
            child: AnimatedOpacity(
              duration: Duration(microseconds: 100),
              opacity:
                  context.watch<ACScoreProvider>().needShowTopMenue ? 1.0 : 0.0,
              child: Container(
                width: double.infinity,
                height: ScreenUtil().setHeight(60),
                color: Colors.black,
              ),
            ),
          )
        ],
      ),
    ),
  );
}
```

这是我运行良好的代码,但是当我尝试将 Widget _topMenu(BuildContext context) 更改为 Widget _topMenu(context) 时,Flutter 给我一个错误:

The following NoSuchMethodError was thrown building Builder(dirty, dependencies: [_InheritedProviderScope<ACScoreProvider>]): Class 'StatelessElement' has no instance method 'watch'. Receiver: Instance of 'StatelessElement'. Tried calling: watch<ACScoreProvider>().The relevant error-causing widget was ChangeNotifierProvider<ACScoreProvider> package:a_class_flutter/…/ac_score/ac_score.dart:9.

为什么缺少BuildContext 声明会导致此错误?我需要将每个上下文都放在 BuildContext 中吗?

【问题讨论】:

  • 您使用的是什么版本的提供程序?是4.1.0以上吗?
  • 是的,它是 Provider 4.1.3

标签: flutter flutter-provider


【解决方案1】:

来自提供商docs

读取值的最简单方法是使用 [BuildContext] 上的扩展方法:

  • context.read&lt;T&gt;(),不听就返回 T

只写Widget _topMenu(context)context 参数被推断为dynamic context 而不是BuildContext context,因此它没有您尝试调用的扩展方法.read&lt;T&gt;()

如果它在StatefulWidget 中,这不会有问题,因为它的State 类有一个实例context(类型BuildContext)属性,因此可以调用扩展方法.read&lt;T&gt;()就可以了。

【讨论】:

  • 还有一个问题,如果没有BuildContext context,它会变成dynamic context,但是这个context 是由父控件上下文或顶部控件上下文的参数传递的。如果父小部件上下文或顶部小部件上下文是BuildContext context 应该没问题,但我尝试在ChangeNotifierProvider builder 函数中添加BuildContext,就像builder: (BuildContext context, child) 一样,但它仍然不起作用
  • 很高兴知道它有帮助。 您可以投票以帮助将来可能需要它的其他人
  • 问题不在于父部件持有什么类型。它与该方法接受的类型有关。因此,即使父亲传递了BuildContext,但该方法推断出dynamic,它也不会起作用,因为任何东西都可以是动态的。
  • 感谢您帮助我。我是 StackOverflow 的新手,所以我的声誉很低,我不能对你的回答投赞成票。但是,真的很感激。
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2018-11-10
  • 2017-10-07
  • 2010-09-27
  • 1970-01-01
  • 2019-07-10
  • 2023-03-21
  • 2022-11-19
相关资源
最近更新 更多