简体   繁体   English

错误:找不到此 Widget 上方的正确 Provider< >

[英]Error: Could not find the correct Provider< > above this Widget

I can't see what I've done wrong in the following, but it's throwing a few provider errors and buildcontext: This happens because you used a BuildContext that does not include the provider of your choice.我看不出我在下面做错了什么,但它抛出了一些提供者错误和 buildcontext: 发生这种情况是因为您使用的BuildContext不包括您选择的提供者。 There are a few common scenarios:有几个常见的场景:

  • You added a new provider in your main.dart and performed a hot-reload.您在main.dart中添加了一个新的提供程序并执行了热重载。 To fix, perform a hot-restart.要修复,请执行热重启。

  • The provider you are trying to read is in a different route.您尝试阅读的提供者在不同的路线上。

    Providers are "scoped".提供者是“范围内的”。 So if you insert of provider inside a route, then other routes will not be able to access that provider.因此,如果您在路由中插入提供者,则其他路由将无法访问该提供者。

  • You used a BuildContext that is an ancestor of the provider you are trying to read.您使用的BuildContext是您尝试读取的提供者的祖先。

    Make sure that SubscriptionsPage is under your MultiProvider/Provider.确保 SubscriptionsPage 在您的 MultiProvider/Provider 下。 This usually happens when you are creating a provider and trying to read it immediately.这通常发生在您创建提供者并尝试立即读取它时。

    For example, instead of:例如,而不是:

     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>()), ), }

    consider using builder like so:考虑像这样使用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);
                  },
                );
              });
        },
      );
    }
  }
}

You need to make sure there is a ChangeNotifierProvider somewhere in the widget tree above the widget, which uses the change notifier.您需要确保在小部件上方的小部件树中某处有一个ChangeNotifierProvider ,它使用更改通知程序。

For example when you call final entitlement = Provider.of<RevenueCatProvider>(context).entitlement;例如,当您调用final entitlement = Provider.of<RevenueCatProvider>(context).entitlement; . . The widget tree gets traversed up in search for a matching ChangeNotifierProvider .遍历小部件树以搜索匹配的ChangeNotifierProvider

The error you receive tells you, there is none.您收到的错误告诉您,没有。

Something like this should work.这样的事情应该有效。

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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (_) => new RevenueCatProvider(),
        child: SubscriptionsPage(),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误无法在此小部件上方找到正确的提供程序 - Error could not find the correct provider above this widget 错误:在此小部件上方找不到正确的提供者 - Error: Could not find the correct Provider above this widget 颤振提供者错误:在此小部件上方找不到正确的提供者 - flutter provider error : Could not find the correct provider above this widget 提供者错误:找不到正确的提供者<Color>在此 MyApp 小部件上方 - Provider Error: Could not find the correct Provider<Color> above this MyApp Widget Flutter 中的提供程序出现错误“无法在此 X Widget 上方找到正确的提供程序” - Provider in Flutter with error "Could not find the correct provider above this X Widget" 错误:找不到正确的提供者<provider2>在这个入职小部件上方</provider2> - Error: Could not find the correct Provider<Provider2> above this Onboarding Widget 错误:找不到正确的提供者<ThemeNotifier>在这个消费者之上<ThemeNotifier>小工具 - Error: Could not find the correct Provider<ThemeNotifier> above this Consumer<ThemeNotifier> Widget 错误:找不到正确的提供者<UserProvider>在此 LoginScreen 小部件上方 - Error: Could not find the correct Provider<UserProvider> above this LoginScreen Widget 错误:找不到正确的提供者<List<PostModel> &gt; 在此 ProfileScreen 小部件上方 - Error: Could not find the correct Provider<List<PostModel>> above this ProfileScreen Widget 错误:找不到正确的提供者<Networkprovider>在这个 Widget 上方 - Error: Could not find the correct Provider<Networkprovider> above this Widget
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM