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

问题描述 投票:0回答:1

当我尝试在我的 flutter 应用程序中加载主屏幕时,出现此错误。

**错误:无法在此 Consumer Widget 上方找到正确的提供者

发生这种情况是因为您使用了不包含提供程序的

BuildContext
您的选择。

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

主屏幕


class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  HomeScreenState createState() => HomeScreenState();
}

@override
class HomeScreenState extends State<HomeScreen> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: ColorConstants.purpleLight,
        title: const Text('Learn Hadith', style: TextStyle(color: Colors.white, fontSize: 20)),
      ),
      body: Consumer<HomeProvider>(
        builder: (context, HomeProvider db, _) {
          switch (db.dataStatus) {
            case DataStatus.Initial:
              db.getCollections(context);
              return SizedBox(height: SizeConfig.screenHeight, width: SizeConfig.screenWidth, child: circularProgressBar());

            case DataStatus.Loading:
              return SizedBox(height: SizeConfig.screenHeight, width: SizeConfig.screenWidth, child: circularProgressBar());

            case DataStatus.Loaded:
              return GridView.builder(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 3 / 2,
                ),
                itemCount: db.collectionList.length,
                itemBuilder: (context, index) {
                  return GestureDetector(
                    onTap: () {
                      if (index == 0) {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => HadithViewScreen(),
                          ),
                        );
                      } else if (index == 1) {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => ChaptersList(collectionId: db.collectionList[index].collectionId!),
                          ),
                        );
                      }
                    },
                    child: CollectionGridItem(collectionDb: db.collectionList[index]),
                  );
                },
              );

            case DataStatus.Failure:
              return Center(child: Text('Error: Something went wrong}'));
          }
        },
      ),
    );
  }
}

class CollectionGridItem extends StatelessWidget {
  final CollectionDb collectionDb;

  const CollectionGridItem({super.key, required this.collectionDb});

  @override
  Widget build(BuildContext context) {
    return Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(35.0),
      ),
      color: ColorConstants.purpleLight,
      child: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(' ${collectionDb.collectionNameEn}', style: const TextStyle(color: Colors.white, fontSize: 15)),
              Text('${collectionDb.collectionNameUr}', style: const TextStyle(color: Colors.white, fontSize: 15)),
            ],
          ),
        ),
      ),
    );
  }
}

I understand that there's something wrong with the way I'm accessing the provider. I tried using the Builder widget as well but i got the same error. Please help how can I solve this?

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      backgroundColor: ColorConstants.purpleLight,
      title: const Text('Learn Hadith', style: TextStyle(color: Colors.white, fontSize: 20)),
    ),
    body: Builder(
      builder: (context) {
        final homeProvider = Provider.of<HomeProvider>(context);
        switch (homeProvider.dataStatus) {
          case DataStatus.Initial:
          case DataStatus.Loading:
            return SizedBox(
              height: SizeConfig.screenHeight,
              width: SizeConfig.screenWidth,
              child: circularProgressBar(),
            );

          case DataStatus.Loaded:
            return GridView.builder(
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 10.0,
                crossAxisSpacing: 10.0,
                childAspectRatio: 3 / 2,
              ),
              itemCount: homeProvider.collectionList.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    if (index == 0) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => HadithViewScreen(),
                        ),
                      );
                    } else if (index == 1) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => ChaptersList(collectionId: homeProvider.collectionList[index].collectionId!),
                        ),
                      );
                    }
                  },
                  child: CollectionGridItem(collectionDb: homeProvider.collectionList[index]),
                );
              },
            );

          case DataStatus.Failure:
            return Center(child: Text('Error: Something went wrong'));
        }
      },
    ),
  );
}

flutter flutter-change-notifier
1个回答
0
投票

每当你想在代码中使用 Provider 时,你需要在访问之前通知 Flutter 该 Provider 正在被使用。这意味着在使用 Consumer 小部件或任何方法访问您的 Provider 之前,您必须使用 Provider 包装祖先小部件之一。

单个小部件或页面的示例

如果您将 Provider 用于特定的小部件或页面,您可以像这样直接包装它:

Provider(
  create: (_) => HomeProvider(),
  child: YourWidget(),
)

使用多个提供商

对于较大的应用程序,建议使用MultiProvider同时创建和管理多个Provider。这样,您就可以在整个应用程序中使用它们。设置方法如下:

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => HomeProvider()),
        // Add other providers here if needed
      ],
      child: MyApp(),
    ),
  );
}

通过使用 MultiProvider 包装您的根小部件,您可以确保所有子小部件都可以访问指定的提供程序,从而使您的代码更干净且更易于维护。

使用提供者进行状态管理有很多值得探索的地方。为此,您可以随时参考官方文档这里

© www.soinside.com 2019 - 2024. All rights reserved.