【问题标题】:Use Provider to provide BLoCs globally to whole flutter module使用 Provider 向整个 Flutter 模块全局提供 BLoC
【发布时间】:2023-04-07 17:13:01
【问题描述】:

https://pub.dev/packages/provider

在没有 MaterialApp 的情况下,我可以使用 Provider 为树下的所有小部件全局提供块吗?我尝试向页面提供 BLoC,但是当我导航到下一页时,找不到 BloC。那么我应该在导航到新页面时提供它,还是有解决方案可以在没有 MaterialApp 的情况下在全球范围内提供它?

目前我正在这样做

Provider
|_MaterialApp
  |_MyPage1 (from which you can navigate to MyPage2...3)

这种方法有效,所有页面都可以访问提供的 BLoC。

但是如果使用这种方法

Provider
  |_MyPage1 (from which you can navigate to MyPage2...3)

MyPage2、MyPage3 找不到提供的 BLoC。 BLoC 只能在 MyPage1 上找到

【问题讨论】:

    标签: flutter provider


    【解决方案1】:

    您可以通过使用MaterialAppbuilder 属性来实现此目的。

    lib/main.dart

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    class SomeBloc {
      final String someValue;
    
      SomeBloc(this.someValue);
    
      void dispose() {}
    }
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      SomeBloc _someBloc = SomeBloc("someValue");
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          builder: (context, widget) => Provider<SomeBloc>(
            create: (_) => _someBloc,
            dispose: (_, bloc) => bloc.dispose(),
            child: widget,
          ),
          initialRoute: '/first-page',
          routes: <String, WidgetBuilder>{
            '/first-page': (context) => FirstPage(),
            '/second-page': (context) => SecondPage(),
          },
        );
      }
    }
    
    class FirstPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        SomeBloc _someBloc = Provider.of<SomeBloc>(context);
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(_someBloc.someValue),
                RaisedButton(
                  child: Text("Open second page"),
                  onPressed: () => Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (_) => SecondPage(),
                    ),
                  ),
                )
              ],
            ),
          ),
        );
      }
    }
    
    class SecondPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        SomeBloc _someBloc = Provider.of<SomeBloc>(context);
    
        return Scaffold(
          body: Center(
            child: Text(_someBloc.someValue),
          ),
        );
      }
    }
    

    根据文档,

    首页

    使用 home 和使用 builder 的区别在于 home 子树被插入到应用程序下面导航器中。

    建造者

    ...从构建器返回的小部件插入上方应用的导航器(如果有)。

    如果您希望在所有路线上提供您的“区块”,则必须在 Navigator 小部件上方提供这些。

    这就是为什么这很简单:

    return Provider(
      create: (_) => _someBloc,
      child: MaterialApp(
        home: FirstPage(),
      ),
    );
    

    在上述设置中,Provider 位于 Navigator 小部件之上。

    这不是:

    return MaterialApp(
      home: Provider(
        create: (_) => _someBloc,
        child: FirstPage(),
      ),
    );
    

    _someBloc 只能由 FirstPage 小部件访问。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-04-29
      • 2020-03-27
      • 2019-10-25
      • 2020-01-27
      • 2021-06-12
      • 2020-09-06
      • 2020-04-21
      • 1970-01-01
      • 2020-12-02
      相关资源
      最近更新 更多