Flutter中的参数类型'Widget Function(BuildContext)'不能分配给参数类型'Widget Function(BuildContext,Widget)'错误
Posted
技术标签:
【中文标题】Flutter中的参数类型\'Widget Function(BuildContext)\'不能分配给参数类型\'Widget Function(BuildContext,Widget)\'错误【英文标题】:The argument type 'Widget Function(BuildContext)' cant be assigned to the parameter type 'Widget Function(BuildContext, Widget)' Error in FlutterFlutter中的参数类型'Widget Function(BuildContext)'不能分配给参数类型'Widget Function(BuildContext,Widget)'错误 【发布时间】:2020-08-30 22:25:54 【问题描述】:这是一个代码:
import 'package:flutter/material.dart';
import 'package:flutterapp/ui/pages/notes_home.dart';
import 'package:provider/provider.dart';
import 'package:flutterapp/ui/pages/splash.dart';
import 'package:flutterapp/ui/pages/user_info.dart';
import 'package:flutterapp/ui/pages/auth/login.dart';
import 'package:flutterapp/model/user_repository.dart';
import 'package:path/path.dart';
class HomePage extends StatelessWidget
@override
Widget build(BuildContext context)
return ChangeNotifierProvider(
builder: (_) => UserRepository.instance(),
child: Consumer
// ignore: missing_return
(builder: (context, UserRepository user, _)
// ignore: missing_return
switch (user.status)
case Status.Uninitialized:
return Splash();
case Status.Unauthenticated:
case Status.Authenticating:
return LoginPage();
case Status.Authenticated:
return NotesHomePage();
),
);
上面代码中的“builder: (_) => UserRepository.instance()”行显示错误
参数类型'Widget Function(BuildContext)'不能赋值给参数类型'Widget Function(BuildContext, Widget)'
每当我运行程序时,它都会显示
在此 LoginPage 小部件上方找不到正确的提供程序
用户存储库代码:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
enum Status Uninitialized, Authenticated, Authenticating, Unauthenticated
class UserRepository with ChangeNotifier
FirebaseAuth _auth;
FirebaseUser _user;
GoogleSignIn _googleSignIn;
Status _status = Status.Uninitialized;
UserRepository.instance()
: _auth = FirebaseAuth.instance,
_googleSignIn = GoogleSignIn()
_auth.onAuthStateChanged.listen(_onAuthStateChanged);
Status get status => _status;
FirebaseUser get user => _user;
Future<bool> signIn(String email, String password) async
try
_status = Status.Authenticating;
notifyListeners();
await _auth.signInWithEmailAndPassword(email: email, password: password);
return true;
catch(e)
_status = Status.Unauthenticated;
notifyListeners();
return false;
Future<bool> signUp(String email, String password) async
try
_status = Status.Authenticating;
notifyListeners();
await _auth.createUserWithEmailAndPassword(email: email, password: password);
return true;
catch(e)
_status = Status.Unauthenticated;
notifyListeners();
return false;
Future<bool> signInWithGoogle() async
try
_status =Status.Authenticating;
notifyListeners();
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
await _auth.signInWithCredential(credential);
return true;
catch(e)
print(e);
_status = Status.Unauthenticated;
notifyListeners();
return false;
Future signOut() async
_auth.signOut();
_googleSignIn.signOut();
_status = Status.Unauthenticated;
notifyListeners();
return Future.delayed(Duration.zero);
Future<void> _onAuthStateChanged(FirebaseUser firebaseUser) async
if(firebaseUser == null)
_status = Status.Unauthenticated;
else
_user = firebaseUser;
_status = Status.Authenticated;
notifyListeners();
请帮忙
enter image description here
这是一个登录页面代码:
import 'package:flutter/material.dart';
import 'package:flutterapp/model/user_repository.dart';
import 'package:provider/provider.dart';
class LoginPage extends StatefulWidget
@override
_LoginPageState createState() => _LoginPageState();
class _LoginPageState extends State<LoginPage>
final GlobalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();
bool signInForm;
@override
void initState()
// TODO: implement initState
super.initState();
signInForm = true;
@override
Widget build(BuildContext context)
final user = Provider.of<UserRepository>(context);
return WillPopScope(
onWillPop: () async
if(!signInForm)
setState(()
signInForm = true;
);
return false;
else
return true;
,
child: Scaffold(
key: _key,
backgroundColor: Colors.red,
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
width: double.infinity,
child: Column(
children: <Widget>[
const SizedBox(height: kToolbarHeight),
Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
width: 60.0,
height: 60.0,
),
const SizedBox(height: 30.0),
RaisedButton(
textColor: Colors.red,
color: Colors.white,
child: Text('Google'),
onPressed: () async
if(!await user.signInWithGoogle())
showmessage();
,
),
const SizedBox(height: 30.0),
AnimatedSwitcher(
child: signInForm ? LoginForm() : SignupForm(),
duration: Duration(milliseconds: 200),
),
const SizedBox(height: 20.0,),
OutlineButton(
textColor: Colors.white,
child: signInForm ? Text("Sign Up", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0),) : Icon(Icons.arrow_back),
onPressed: ()
setState(()
signInForm = !signInForm;
);
,
color: Colors.white,
borderSide: BorderSide(color: Colors.white),
highlightColor: Colors.white,
)
],
),
)
),
),
);
void showmessage()
_key.currentState.showSnackBar(SnackBar(
content: Text("Somethimg is wrong"),
));
class LoginForm extends StatefulWidget
final Function showError;
const LoginForm(Key key, this.showError) : super(key: key);
@override
_LoginFormState createState() => _LoginFormState();
class _LoginFormState extends State<LoginForm>
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final FocusNode passwordField = FocusNode();
TextEditingController _email;
TextEditingController _password;
@override
void initState()
_email = TextEditingController();
_password = TextEditingController();
super.initState();
@override
Widget build(BuildContext context)
final user = Provider.of<UserRepository>(context);
return Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Text("Login", style: Theme.of(context).textTheme.display1,),
const SizedBox(height: 20.0),
TextFormField(
controller: _email,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Email"
),
onEditingComplete: ()
FocusScope.of(context).requestFocus(passwordField);
,
),
const SizedBox(height: 16.0,),
TextFormField(
controller: _password,
focusNode: passwordField,
obscureText: true,
decoration: InputDecoration(
labelText: "Password"
),
),
const SizedBox(height: 20.0),
RaisedButton(
textColor: Colors.red,
child: Text("Login"),
onPressed: () async
if(_formKey.currentState.validate())
if(!await user.signIn(
_email.text, _password.text))
widget.showError();
,
)
],
),
),
);
class SignupForm extends StatefulWidget
@override
_SignupFormState createState() => _SignupFormState();
class _SignupFormState extends State<SignupForm>
final FocusNode passwordField = FocusNode();
final FocusNode confirmPasswordField = FocusNode();
TextEditingController _email;
TextEditingController _password;
TextEditingController _confirmpassword;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
void initState()
_email = TextEditingController();
_password = TextEditingController();
_confirmpassword = TextEditingController();
super.initState();
@override
Widget build(BuildContext context)
final user = Provider.of<UserRepository>(context);
return Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Text("Sign Up", style: Theme.of(context).textTheme.display1,),
const SizedBox(height: 20.0),
TextFormField(
controller: _email,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Email"
),
onEditingComplete: ()
FocusScope.of(context).requestFocus(passwordField);
,
),
const SizedBox(height: 16.0,),
TextFormField(
obscureText: true,
controller: _password,
focusNode: passwordField,
decoration: InputDecoration(
labelText: "Password"
),
onEditingComplete: ()=> FocusScope.of(context).requestFocus(confirmPasswordField),
),
const SizedBox(height: 16.0,),
TextFormField(
obscureText: true,
controller: _confirmpassword,
focusNode: confirmPasswordField,
decoration: InputDecoration(
labelText: "Confirm Password"
),
onEditingComplete: ()
FocusScope.of(context).requestFocus(passwordField);
,
),
const SizedBox(height: 20.0),
RaisedButton(
textColor: Colors.red,
child: Text("Create Account"),
onPressed: () async
if(_formKey.currentState.validate())
if(_confirmpassword.text == _password.text)
if(!await user.signUp(
_email.text, _password.text))
print("Failed to Signup");
,
)
],
),
),
);
【问题讨论】:
【参考方案1】:在您的代码中,只需更改
builder: (_) => UserRepository.instance(),
到
create: (_) => UserRepository.instance(),
一切都会好起来的!
【讨论】:
谢谢。这让我很开心。花了一天时间找出错误消息,但我自己无法解决。再次感谢。【参考方案2】:对于 provider 3.2 及更高版本,您应该使用 create 而不是 builder
【讨论】:
【参考方案3】:我是 Flutter 的新手,遇到了同样的问题,然后我用这个解决方案解决了..
我将
builder
替换为create
,如图所示。
【讨论】:
【参考方案4】:从 5.0.0 版本的提供程序包开始,我们应该在 ChangeNotifierProvider 中使用 'create' 而不是 'builder' 。 p>
【讨论】:
【参考方案5】:使用 create: 代替 builder: in ChangeNotifiereProvider()
【讨论】:
【参考方案6】:试试这个:
class HomePage extends StatelessWidget
@override
Widget build(BuildContext context)
return ChangeNotifierProvider<UserRepository>(
create: (context) => UserRepository.instance(),
child: Consumer
// ignore: missing_return
(builder: (context, UserRepository user, child)
// ignore: missing_return
switch (user.status)
case Status.Uninitialized:
return Splash();
case Status.Unauthenticated:
case Status.Authenticating:
return LoginPage();
case Status.Authenticated:
return NotesHomePage();
),
);
【讨论】:
android studio 中的错误消失了,使用上面的代码也完成了安装,但在 Mobile 中它无法正常工作。在屏幕上启动后显示错误:在此 LoginPage 小部件上方找不到正确的 Provider以上是关于Flutter中的参数类型'Widget Function(BuildContext)'不能分配给参数类型'Widget Function(BuildContext,Widget)'错误的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 参数类型 'List<dynamic>' 不能分配给参数类型 'List<Widget>'
Flutter 错误:无法将参数类型“List<Future<Widget>>”分配给参数类型“List<Widget>”
如何有条件地将参数传递给 Flutter/Dart 中的 Widget?
将 Future 类型化结果从函数分配给 Flutter Widget 中的变量
参数类型“Widget Function(Categoria)”不能分配给参数类型“dynamic Function(Child)”。 (型号)颤振