flutter 如何在不使用MultiProvider Package MaterialApp的情况下初始化Provider

zf9nrax1  于 2023-06-07  发布在  Flutter
关注(0)|答案(2)|浏览(322)

是否有替代方法来初始化Provider,而不是使用MaterialApp和MultiProvider Package 它?
我目前正在使用Provider来管理Flutter应用程序中的状态。我正在使用MultiProvider Package 我的MaterialApp小部件,以初始化我的所有提供程序。但是,我想知道是否有更有效的方法来做到这一点。
我试图在构建小部件时创建一个提供程序,但这里的问题是,当导航到另一个屏幕时,它显示未找到提供程序异常,如果我们在该小部件上创建一个新示例,则整个数据都会更改。
有没有一种方法可以初始化Provider,而不使用MultiProvider的MaterialApp Package 它?如果是这样,最好的方法是什么?
谢谢你的帮助!

mwg9r5ms

mwg9r5ms1#

您可以在当前路由上创建providing,但要访问它,您需要分离上下文。

return ChangeNotifierProvider<Counter>(
  create: (_) => Counter(),
    child: Builder(
      builder: (context) {
        // we cant accass the context of the provider within same context while context
        return Scaffold(

现在在下一个路由上传递当前提供程序

final value = context.read<Counter>();
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => ChangeNotifierProvider<Counter>.value(
      value: value,
      builder: (context, child) {
        return const NextPage();
      },
    ),
  ),
);

测试片段

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class Counter extends ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Counter>(
      create: (_) => Counter(),
      child: Builder(
        builder: (context) {
          // we cant accass the context of the provider within same context while context
          return Scaffold(
              body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Consumer<Counter>(
                  builder: (context, Counter counter, child) {
                    return Text("Count: ${counter.count}");
                  },
                ),
                ElevatedButton(
                  onPressed: () {
                    context.read<Counter>().increment();
                  },
                  child: const Text("Increment"),
                ),
                ElevatedButton(
                  onPressed: () {
                    final value = context.read<Counter>();
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => ChangeNotifierProvider<Counter>.value(
                          value: value,
                          builder: (context, child) {
                            return const NextPage();
                          },
                        ),
                      ),
                    );
                  },
                  child: const Text("Next Page"),
                ),
              ],
            ),
          ));
        },
      ),
    );
  }
}

class NextPage extends StatelessWidget {
  const NextPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Next Page"),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Consumer<Counter>(
              builder: (context, Counter counter, child) {
                return Text("Count: ${counter.count}");
              },
            ),
            ElevatedButton(
              onPressed: () {
                context.read<Counter>().increment();
              },
              child: const Text("Increment"),
            ),
          ],
        ),
      ),
    );
  }
}
jum4pzuy

jum4pzuy2#

我恐怕没有其他选择,如果你想声明多个提供者,你将需要在某个时候实现MultiProvider,关于使用MaterialApp,这取决于你,因为你可以在不使用MaterialApp的情况下实现MultiProvider,但我不建议你这样做,因为MaterialApp定义了一些限制你的应用如何呈现,比如顶部的边距。关于你的问题的另一部分,当你在一个小部件内定义一个提供程序时,这将只适用于子小部件,这意味着父小部件内的小部件,如:

// This works, a child widget can access its parent provider
ParentWidget(Defines Provider A) --> ChildWidget(Consumes Provider A)
// this doesn't work, a parent widget can't access a provider defined on a nested widget
ParentWidget(Cannot consume Provider A) --> ChildWidget(Defines Provider A) --> DeeperChildWidget(Consumes Provider A)

既然这是清楚的,我想知道,为什么你想避免使用MultiProvider有一个具体的原因吗?

相关问题