Flutter cubit blocprovider 找不到正确的提供者

Posted

技术标签:

【中文标题】Flutter cubit blocprovider 找不到正确的提供者【英文标题】:Flutter cubit blocprovider couldn't find the correct provider 【发布时间】:2021-04-04 16:26:14 【问题描述】:

我正在构建一个颤振应用程序,用户可以在其中使用谷歌帐户登录。我想用肘来管理这个。我使用 Blocprovider 在小部件树中提供肘部。块提供者位于 runApp 函数中的 futurebuilder 中。这是我的代码: main.dart:

home: FutureBuilder(
          future: initRepo.initialize(),
          builder: (context, snapshot) 
            if (snapshot.connectionState == ConnectionState.done) 
              return BlocProvider(
                  create: (context) => SignInCubit(googleAuthRepo),
                  child: SignInPage(googleAuthRepo, initRepo, databaseRepo));
            
            return SplashScreen();
          ,
        ));

SignInPage 小部件:

class SignInPage extends StatelessWidget 
  final GoogleAuthRepo _googleAuthRepo;
  final InitRepo initRepo;
  final DatabaseRepo _databaseRepo;

  SignInPage(this._googleAuthRepo, this.initRepo, this._databaseRepo);

  @override
  Widget build(BuildContext context) 
    return Container(
      decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: [Colors.grey[900], Colors.grey[800]])),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Image(image: AssetImage("lib/assets/icon.png")),
          BlocBuilder(
            builder: (context, state)
              if(state is SignInInitial)
                return buildInitial();
              
              else if(state is SignInLoading)
                return buildLoading();
              
              else if(state is SignInLoaded)
                return buildLoaded();
              
              return buildInvalidUser();
            ,
          )
        ],
      ),
    );
  

  Widget buildInitial() 
    return GoogleButton(
        this._databaseRepo, this.initRepo, this._googleAuthRepo);
  

  Widget buildLoading() 
    return CircularProgressIndicator(
      valueColor: new AlwaysStoppedAnimation<Color>(
        Colors.blueGrey,
      ),
    );
  

  Widget buildInvalidUser() 
    return Column(
      children: [
        GoogleButton(this._databaseRepo, this.initRepo, this._googleAuthRepo),
        Text(
          "Bejelentkezési hiba. Használj e5vos.hu-s e-mail címet!", //This is an error message, if the user doesn't use a specific email domain
          style: TextStyle(color: Colors.red),
        )
      ],
    );
  

  Widget buildLoaded()
    return MainPage(_databaseRepo, initRepo);
  

GoogleButton 小部件:

class GoogleButton extends StatefulWidget 
  @override
  _GoogleButtonState createState() => _GoogleButtonState();

  final DatabaseRepo databaseRepo;
  final InitRepo initRepo;
  final GoogleAuthRepo _googleAuthRepo;

  GoogleButton(this.databaseRepo, this.initRepo, this._googleAuthRepo);


class _GoogleButtonState extends State<GoogleButton> 

  @override
  Widget build(BuildContext context) 
    return Center(
      child: Container(
        height: MediaQuery.of(context).size.height / 15,
        width: MediaQuery.of(context).size.width / 7,
        child: ButtonTheme(
          minWidth: 300,
          child: OutlineButton(
              borderSide: BorderSide(color: Colors.blueGrey, width: 1),
              shape:
                  RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
              onPressed: () async 
                final signInCubit = BlocProvider.of<SignInCubit>(context);
                signInCubit.signInWithGoogle();
              ,
              child: Padding(
                padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                child: Center(
                        child:
                          Text(
                              'Bejelentkezés',
                              style: TextStyle(
                                fontSize: 20,
                                color: Colors.blueGrey,
                              ),
                            ),
                      ),
              )),
        ),
      ),
    );
  

当我运行它时,它会抛出以下错误:

我尝试按照它的建议做并将 BlocProvider 与 Provider 交换,所以我的代码如下所示:

home: FutureBuilder(
          future: initRepo.initialize(),
          builder: (context, snapshot) 
            if (snapshot.connectionState == ConnectionState.done) 
              return Provider<SignInCubit>(
                create: (context) => SignInCubit(googleAuthRepo),
                builder: (context) 
                  return SignInPage(googleAuthRepo, initRepo, databaseRepo)
                  ,
                ,);
            
            return SplashScreen();
          ,
        ));

然后我得到参数类型“SignInPage Function(BuildContext)”不能分配给参数类型“Widget Function(BuildContext, Widget)”错误。

【问题讨论】:

【参考方案1】:

我想需要查看您的 SignInPage 代码。目前,您似乎缺少 BlocBuilder 作为 BlocProvider 的子级。

一般来说,您的结构看起来有点“混合”。为什么将 BlocProvider 用作 FutureBuilder 的子级?我将初始化 bloc,该 bloc 依次初始化所有必要的数据,一旦准备就绪,就会产生渲染屏幕的状态(以及在那之前的活动指示器)

【讨论】:

感谢您的回复。我编辑了问题,从现在开始包含额外的代码。 您应该将 BlocBuilder 语句更改为 BlocBuilder&lt;MyBlocClass, MyBlocState&gt;(builder:

以上是关于Flutter cubit blocprovider 找不到正确的提供者的主要内容,如果未能解决你的问题,请参考以下文章

BlocProvider.of() 调用的上下文不包含 CounterBloc 类型的 Cubit

BlocProvider.of() 调用的上下文不包含 MyBloc 类型的 Bloc/Cubit

Flutter - cubit - 改变cubit内的布尔值

Flutter - Cubit 和一些需要澄清

在 Flutter 中,有没有像 root Saga 这样的 root BLoC 模式?

Flutter:单元测试一个 Cubit 问题