问题描述
我正在构建一个 Flutter 应用程序,用户可以在其中使用 Google 帐户登录。我想用 cubit 来管理这个。我使用 Blocprovider 在小部件树中提供肘。 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._googleAuthRepo);
}
Widget buildLoading() {
return CircularProgressIndicator(
valueColor: new AlwaysstoppedAnimation<Color>(
Colors.blueGrey,);
}
Widget buildInvalidUser() {
return Column(
children: [
GoogleButton(this._databaseRepo,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._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,10),child: Center(
child:
Text(
'Bejelentkezés',style: TextStyle(
fontSize: 20,color: Colors.blueGrey,)),);
}
}
当我运行它时,它抛出以下错误:
我尝试按照它的建议进行操作并将 BlocProvider 与 Provider 交换,因此我的代码如下所示:
home: FutureBuilder(
future: initRepo.initialize(),snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Provider<SignInCubit>(
create: (context) => SignInCubit(googleAuthRepo),builder: (context) {
return SignInPage(googleAuthRepo,databaseRepo),},);
}
return SplashScreen();
},));
但后来我得到参数类型“SignInPage Function(BuildContext)”无法分配给参数类型“Widget Function(BuildContext,Widget)”错误。
解决方法
我想人们需要查看您的 SignInPage 代码。目前,您似乎缺少 BlocBuilder 作为 BlocProvider 的子代。
总的来说,您的结构看起来有点“混合”。为什么将 BlocProvider 用作 FutureBuilder 的子代?我会初始化 bloc,它依次初始化所有必要的数据,一旦准备就绪,就会产生呈现屏幕的状态(以及在此之前的活动指示器)