错误:无法在此小部件上方找到正确的提供者< >

2024-03-10

我看不出我在下面做错了什么,但它抛出了一些提供程序错误和构建上下文: 发生这种情况是因为您使用了BuildContext不包括提供者 你的选择。有以下几种常见场景:

  • 您在您的目录中添加了一个新的提供商main.dart并执行热重载。 要修复,请执行热重启。

  • 您尝试阅读的提供商处于不同的路线。

    提供者是“有范围的”。因此,如果您在路线中插入提供者,那么 其他路由将无法访问该提供商。

  • 你用了一个BuildContext这是您正在尝试阅读的提供者的祖先。

    确保 SubscriptionsPage 位于您的 MultiProvider/Provider 下。 当您创建提供程序并尝试立即读取它时,通常会发生这种情况。

    例如,代替:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // Will throw a ProviderNotFoundError, because `context` is associated
        // to the widget that is the parent of `Provider<Example>`
        child: Text(context.watch<Example>()),
      ),
    }
    

    考虑使用builder像这样:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // we use `builder` to obtain a new `BuildContext` that has access to the provider
        builder: (context) {
          // No longer throws
          return Text(context.watch<Example>()),
        }
      ),
    }
    
        
    

    class RevenueCatProvider extends ChangeNotifier{
          RevenueCatProvider() {
            init();
          }
          Entitlement _entitlement = Entitlement.free;
          Entitlement get entitlement => _entitlement;
          Future init() async {
            Purchases.addPurchaserInfoUpdateListener((purchaserInfo) async {
              updatePurchasesStatus();
            });
          }
          Future updatePurchasesStatus() async {
            final purchaserInfo = await Purchases.getPurchaserInfo();
            final entitlements = purchaserInfo.entitlements.active.values.toList();
            _entitlement = entitlements.isEmpty ? Entitlement.free : Entitlement.pro;
            notifyListeners();
          }
        }

class SubscriptionsPage extends StatefulWidget {
  const SubscriptionsPage({Key? key}) : super(key: key);

  @override
  State<SubscriptionsPage> createState() => _SubscriptionsPageState();
}

class _SubscriptionsPageState extends State<SubscriptionsPage> {
  bool isLoading = false;

  @override
  Widget build(BuildContext context) {

    final entitlement = Provider.of<RevenueCatProvider>(context).entitlement;

   return Scaffold(
      appBar: AppBar(
        title: const Text('Subscription Page'),
      ),
      body: Container(
        alignment: Alignment.center,
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            buildEntitlement(entitlement),
            const SizedBox(height: 32),
            Padding(
              padding: const EdgeInsets.only(left: 20.0, right: 20),
              child: ElevatedButton(
                style: ElevatedButton.styleFrom(
                  minimumSize: const Size.fromHeight(50),
                ),
                child: const Text(
                  'See Available Plans',
                  style: TextStyle(fontSize: 20),
                ),
                onPressed: () => isLoading ? null : fetchOffers,
              ),
            ),
            const SizedBox(height: 32),
            SizedBox(
              height: 200,
              child: Image.asset('images/logo_transparent.png'),
            ),
          ],
        ),
      ),
    );
  }


  Widget buildEntitlement(Entitlement entitlement) {

    switch (entitlement) {
      case Entitlement.pro:
        return Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: const [
            SizedBox(height: 40),
            Text('You are on a Paid plan',
              style: TextStyle(
                fontSize: 20,
              ),
            ),
            SizedBox(height: 10),
            Icon(Icons.paid,
              size: 100,
            ),
          ],
        );
      case Entitlement.free:
      default:
        return Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: const [
            SizedBox(height: 40),
            Text('You are on a Free plan',
              style: TextStyle(
                fontSize: 20,
              ),
            ),
            SizedBox(height: 10),
            Icon(Icons.lock,
              size: 100,
            ),
          ],
        );
    }
  }


  Future fetchOffers() async {
    final offerings = await PurchaseApi.fetchOffers();

    if (offerings.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
        content: Text('No Subscription'),
      ));
    } else {
      final packages = offerings
          .map((offer) => offer.availablePackages)
          .expand((pair) => pair)
          .toList();


       showModalBottomSheet(
        useRootNavigator: true,
        isDismissible: true,
        isScrollControlled: true,
        backgroundColor: kLightPrimary,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
        ),
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setModalState) {
                return PaywallWidget(
                  packages: packages,
                  title: '⭐️ Upgrade your plan',
                  description: 'Upgrade your plan to enjoy unlimited ad-free reviews',
                  onClickedPackage: (package) async {
                    await PurchaseApi.purchasePackage(package);
                    Navigator.pop(context);
                  },
                );
              });
        },
      );
    }
  }
}

您需要确保有一个ChangeNotifierProvider位于小部件树上方的某个位置,该小部件使用更改通知程序。

例如当你打电话时final entitlement = Provider.of<RevenueCatProvider>(context).entitlement;。遍历小部件树以搜索匹配的ChangeNotifierProvider.

您收到的错误告诉您,没有。

像这样的东西应该有效。

class Sample extends StatelessWidget {
  const Sample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (_) => new RevenueCatProvider(),
        child: SubscriptionsPage(),
    );
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

错误:无法在此小部件上方找到正确的提供者< > 的相关文章

  • flutter stepper 小部件 - 验证各个步骤中的字段

    我正在使用步进器小部件来收集用户信息并对其进行验证 我需要在每个步骤调用 API 因此在每个继续按钮的步骤中验证每个字段 我正在使用表单状态和表单小部件 但是问题是它验证步进器中所有步骤中的整个字段 我如何仅验证步进器中的单个步骤 我浏览了
  • 如何结合GetX和build_value的使用?

    我们的应用程序有很多提供商 https pub dev packages provider https pub dev packages provider 使用的代码built value https pub dev packages bu
  • 使用 flutter 处理 Appcheck 时出错

    我想在 firebase 存储中上传文件 但经过多次研究后出现了 appcheck 错误 我发现我必须在 firebase 上激活 Appcheck 而且还要在我的应用程序上激活它 在 youtube 上的谷歌视频中 我看到我必须在构建我的
  • GetX 解绑流

    我正在使用bindStream 函数与GetX封装在控制器内 class FrediUserController extends GetxController override void onReady super onReady fina
  • 当 flutter 应用程序终止时,普通推送通知会默默出现或根本不出现

    我在 nodejs 上使用 firebase admin 向用户发送推送通知 https firebase google com docs admin setup https firebase google com docs admin s
  • Flutter 中没有上下文的 AlertDialog

    我想在 http 获取失败时显示 AlertDialog 函数显示对话框 https api flutter dev flutter material showDialog html https api flutter dev flutte
  • Flutter Firebase 身份验证 currentUser() 返回 null

    这是关于 Flutter Firebase 身份验证插件的 我试图在创建新用户后发送验证电子邮件 但 sendEmailVerification 内部使用 currentUser 这对我来说似乎是一个错误 但为了以防万一 我在 stacko
  • 在 dart 的 MultipartRequest 中添加授权标头

    我在用多部分请求 https pub dartlang org documentation http latest http MultipartRequest class html在 Dart 中以便将文件上传到 API 但是我需要在我的请
  • BottomAppBar浮动操作按钮凹口/插入不透明

    我添加了一个BottomAppBar到材质应用程序中的脚手架 并且我添加了一个在中心带有插图的工厂 代码看起来有点像这样 Scaffold bottomNavigationBar BottomAppBar color Theme of co
  • 颤振预览图标在代码完成时显示损坏的资源图像

    当我第一次安装 flutter 和 dart 扩展时 图标预览工作正常 但是当我在没有 wi fi 的环境中开发时 图标预览损坏了 不确定这是问题所在 我尝试重新安装所有与 flutter 和 dart 相关的扩展 但问题仍然存在 如果有任
  • 如何修复 webview_flutter 中的白屏?

    运行 webview flutter 示例应用程序 https github com flutter plugins tree master packages webview flutter example https github com
  • Flutter - 构建失败并出现异常

    当我启动我的应用程序时 我收到此错误消息 自上次运行以来我没有进行任何更改 当时一切都很好 有人知道如何解决这个问题吗 谢谢 FAILURE Build failed with an exception 什么地方出了错 无法确定任务 app
  • 如何更改 ElevatedButton 颜色或阴影 Flutter

    我当时用的是RaisedButton直到 Flutter 弃用了它 我们不能再使用它了 有一个建议说 使用ElevatedButton相反 所以我尝试使用它 但我看不到类似的属性color elevation focusColor etc
  • Flutter Spotify Api 身份验证

    我需要在使用 Spotify api 的 Flutter 应用程序中对用户进行身份验证 我使用 flutter web auth 打开 WebView 并让用户在那里登录 我无法返回应用程序 在 Spotify 仪表板中 我将回调 Uri
  • 如何在 Flutter Provider 中删除 StreamController 中的数据?

    我正在使用provider来构建我的应用程序 因此数据被添加到StreamController中 每次刷新我的应用程序时 它都会调用API 然后将数据推送到StreamController 问题是如何在替换之前删除数据新的那一个 contr
  • 如何将额外的文本添加到颤振谷歌地图自定义标记中?

    问题是如何将自定义谷歌地图标记上的文本重叠与代表车辆登记号的文本融合在一起 我尝试使用此方法将文本叠加在图标上 生成器 上下文 gt 但根本不被认可 class MapsDemo extends StatefulWidget overrid
  • 扑。应用程序不会崩溃并发送崩溃报告

    我已经集成了Firebase Crashlytics在我的应用程序中 我正在测试 Android 应用程序 我强迫崩溃来检查它 if true List arr throw arr 1 2 我的问题是应用程序不会崩溃 我只是在日志中得到这个
  • 如何在 flutter 中仅显示列表中的 5 项

    我想在 flutter 中显示一个列表 我正在使用listView 问题是我只想显示 5 个项目 我的意思是当用户向下滚动时我想从开始索引中删除并将另一个小部件添加到包含我的小部件的列表的末尾 但是当我这样做时ScrollView 不会停留
  • Flutter 网络图像作为 Google 地图标记

    我想在屏幕上的谷歌地图上添加网络图像作为标记 API确实支持一个功能Bitmapdescriptor fromBytes 但是 我不知道如何将它与网络图像一起使用 BitmapDescriptor fromBytes byteData 首先
  • Flutter http请求上传mp3文件

    我使用这个 api 上传 mp3 文件 使用这种方法 Future

随机推荐