参数类型"String?"无法分配给参数类型"String"。dart(argument_type_not_assignable。(
try{
var key = 'email';
await Provider.of<Authentication>(context, listen: false).signUp(
_authData[key],
_authData['password']
);
Navigator.of(context).pushReplacementNamed(HomeScreen.routeName);
} catch(error)
{
var errorMessage = 'Authentication Failed. Please try again later.';
_showErrorDialog(errorMessage);
}
}
try{
await Provider.of<Authentication>(context, listen: false).logIn(
_authData['email'],
_authData['password']
);
Navigator.of(context).pushReplacementNamed(HomeScreen.routeName);
} catch (error)
{
var errorMessage = 'Authentication Failed. Please try again later.';
_showErrorDialog(errorMessage);
}
}
屏幕截图
屏幕截图
这是null safety
的一个问题。基本上,您的signUp
方法接受一个String作为参数,但您正在传递一个String?(问号表示valute可以为null(。为了解决这种情况,您必须检查_authData[key]
和_authData['password']
(同样适用于logIn(是否为空。类似这样的东西:
try{
var key = 'email';
if(_authData[key] != null && _authData['password'] != null) {
await Provider.of<Authentication>(context, listen: false).signUp(
_authData[key]!,
_authData['password']!,
);
Navigator.of(context).pushReplacementNamed(HomeScreen.routeName);
} else {
throw Exception('Error');
}
} catch(error) {
var errorMessage = 'Authentication Failed. Please try again later.';
_showErrorDialog(errorMessage);
}
缺少"State.build"的具体实现。尝试实现缺失的方法,或者使类抽象。dart(non_abstract_class_inherits_abstrac_member(
signup_screen.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/authentication.dart';
import 'home_screen.dart';
import 'login_screen.dart';
class SignupScreen extends StatefulWidget {
static const routeName = '/signup';
@override
_SignupScreenState createState() => _SignupScreenState();
}
class _SignupScreenState extends State<SignupScreen> {
final GlobalKey<FormState> _formKey = GlobalKey();
TextEditingController _passwordController = new TextEditingController();
Map<String, String> _authData = {
'email' : '',
'password' : ''
};
void _showErrorDialog(String msg)
{
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An Error Occured'),
content: Text(msg),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: (){
Navigator.of(ctx).pop();
},
)
],
)
);
}
Future<void> _submit() async
{
if(!_formKey.currentState!.validate())
{
return;
}
_formKey.currentState!.save();
try{
var key = 'email';
if(_authData[key] != null && _authData['password'] != null) {
await Provider.of<Authentication>(context, listen: false).signUp(
_authData[key]!,
_authData['password']!,
);
Navigator.of(context).pushReplacementNamed(HomeScreen.routeName);
} else {
throw Exception('Error');
}
} catch(error) {
var errorMessage = 'Authentication Failed. Please try again later.';
_showErrorDialog(errorMessage);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Signup'),
actions: <Widget>[
FlatButton(
child: Row(
children: <Widget>[
Text('Login'),
Icon(Icons.person)
],
),
textColor: Colors.white,
onPressed: (){
Navigator.of(context).pushReplacementNamed(LoginScreen.routeName);
},
)
],
),
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.limeAccent,
Colors.redAccent,
]
)
),
),
Center(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
height: 300,
width: 300,
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
//email
TextFormField(
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value)
{
if(value!.isEmpty || !value.contains('@'))
{
return 'invalid email';
}
return null;
},
onSaved: (value)
{
_authData['email'] = value!;
},
),
//password
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: _passwordController,
validator: (value)
{
if(value!.isEmpty || value.length<=5)
{
return 'invalid password';
}
return null;
},
onSaved: (value)
{
_authData['password'] = value!;
},
),
//Confirm Password
TextFormField(
decoration: InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
validator: (value)
{
if(value!.isEmpty || value != _passwordController.text)
{
return 'invalid password';
}
return null;
},
onSaved: (value)
{
},
),
SizedBox(
height: 30,
),
RaisedButton(
child: Text(
'Submit'
),
onPressed: ()
{
_submit();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
color: Colors.blue,
textColor: Colors.white,
)
],
),
),
),
),
),
)
],
),
);
}
}
}
login_screen.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'signup_screen.dart';
import 'home_screen.dart';
import '../models/authentication.dart';
class LoginScreen extends StatefulWidget {
static const routeName = '/login';
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final GlobalKey<FormState> _formKey = GlobalKey();
Map<String, String> _authData = {
'email' : '',
'password': ''
};
var email;
void _showErrorDialog(String msg)
{
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An Error Occured'),
content: Text(msg),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: (){
Navigator.of(ctx).pop();
},
)
],
)
);
}
Future<void> _submit() async
{
if(!_formKey.currentState!.validate())
{
return;
}
_formKey.currentState!.save();
try{
if(_authData[email] != null && _authData['password'] != null) {
await Provider.of<Authentication>(context, listen: false).logIn(
_authData['email']!,
_authData['password']!,
);
Navigator.of(context).pushReplacementNamed(HomeScreen.routeName);
} else {
throw Exception('Error');
}
} catch(error) {
var errorMessage = 'Authentication Failed. Please try again later.';
_showErrorDialog(errorMessage);
}}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
actions: <Widget>[
FlatButton(
child: Row(
children: <Widget>[
Text('Signup'),
Icon(Icons.person_add)
],
),
textColor: Colors.white,
onPressed: (){
Navigator.of(context).pushReplacementNamed(SignupScreen.routeName);
},
)
],
),
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.lightGreenAccent,
Colors.blue,
]
)
),
),
Center(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
height: 260,
width: 300,
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
//email
TextFormField(
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value)
{
if(value!.isEmpty || !value.contains('@'))
{
return 'invalid email';
}
return null;
},
onSaved: (value)
{
_authData['email'] = value!;
},
),
//password
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value)
{
if(value!.isEmpty || value.length<=5)
{
return 'invalid password';
}
return null;
},
onSaved: (value)
{
_authData['password'] = value!;
},
),
SizedBox(
height: 30,
),
RaisedButton(
child: Text(
'Submit'
),
onPressed: ()
{
_submit();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
color: Colors.blue,
textColor: Colors.white,
)
],
),
),
),
),
),
)
],
),
);
}
}
照片