如何在 Flutter 中使用全局键制作 StatefulWidget?
How to make StatefulWidget with global key in Flutter?
我是 Flutter 的新手,我想我的设置可能很奇怪。到目前为止的大部分设置都来自小型教程。我目前 main.dart 只呈现一个 userCheck 小部件,它最终将用于连接后端并检查我是否拥有有效的用户令牌。
class UserCheck extends StatefulWidget {
const UserCheck({Key key}) : super(key: key);
@override
UserCheckState createState() => UserCheckState();
}
class UserCheckState extends State<UserCheck> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var userExists = false;
@override
Widget build(BuildContext context) {
return userExists
? Home()
: new LoginForm();
}
}
如果有合适的用户,Home Widget 最终会从后端加载信息。现在,userExists 显然默认为 false。这会很好地加载 LoginForm。我目前的目标是当用户登录时,假设这是一个好的登录,然后将 userExists 反转为 true,从而打开主页。这是登录表单设置:
LoginForm({Key key}) : super(key: key);
UserCheckState parent;
@override
LoginFormState createState() => LoginFormState();
}
class LoginFormState extends State<LoginForm> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var userData = {};
bool login = true;
String loginText = 'Sign Up';
void updateField(String value, String field) {
setState(() {
userData = {
...userData,
'$field': value,
};
});
}
void sendHome() {
setState(() {
// this.parent.parent.userExists = true;
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(children: <Widget>[
login
? Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
decoration: const InputDecoration(
hintText: 'Enter a username', labelText: 'Username'),
validator: (String value) {
if (value == null || value.isEmpty) {
return 'Please enter a username';
}
updateField(value, 'username');
return null;
},
),
TextFormField(
obscureText: true,
enableSuggestions: false,
autocorrect: false,
decoration: const InputDecoration(
hintText: 'Enter your password',
labelText: 'Password'),
validator: (String value) {
if (value == null || value.isEmpty) {
return 'Please enter a password';
}
updateField(value, 'password');
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () {
print('hit here');
if (_formKey.currentState.validate()) {
print('hit here two');
sendHome();
print(userData);
// if API responds with proper token
// API call to login
}
},
child: Text('Submit'),
),
),
],
),
)
: SignupForm(),
ElevatedButton(
onPressed: () {
setState(() {
login = !login;
loginText = loginText == 'Sign Up' ? 'Log In' : 'Sign Up';
});
},
child: Text(loginText),
)
]),
);
}
}```
I don't know if there's some sort of router that would be better and is already implemented as switching Widgets, but I haven't found anything from my own searches.
如果用户登录,您不必返回到 userCheck
小部件。相反,您可以使用 Navigator
直接转到 Home
屏幕,使从 Login
页面到 Home
页面的转换。将导航器放在用户在 Submit
按钮的 onPressed
函数中获取有效令牌的行之后:
ElevatedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
// Goes to Home screen.
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Home(),
));
}
},
child: Text('Submit'),
),
我是 Flutter 的新手,我想我的设置可能很奇怪。到目前为止的大部分设置都来自小型教程。我目前 main.dart 只呈现一个 userCheck 小部件,它最终将用于连接后端并检查我是否拥有有效的用户令牌。
class UserCheck extends StatefulWidget {
const UserCheck({Key key}) : super(key: key);
@override
UserCheckState createState() => UserCheckState();
}
class UserCheckState extends State<UserCheck> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var userExists = false;
@override
Widget build(BuildContext context) {
return userExists
? Home()
: new LoginForm();
}
}
如果有合适的用户,Home Widget 最终会从后端加载信息。现在,userExists 显然默认为 false。这会很好地加载 LoginForm。我目前的目标是当用户登录时,假设这是一个好的登录,然后将 userExists 反转为 true,从而打开主页。这是登录表单设置:
LoginForm({Key key}) : super(key: key);
UserCheckState parent;
@override
LoginFormState createState() => LoginFormState();
}
class LoginFormState extends State<LoginForm> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
var userData = {};
bool login = true;
String loginText = 'Sign Up';
void updateField(String value, String field) {
setState(() {
userData = {
...userData,
'$field': value,
};
});
}
void sendHome() {
setState(() {
// this.parent.parent.userExists = true;
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(children: <Widget>[
login
? Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
decoration: const InputDecoration(
hintText: 'Enter a username', labelText: 'Username'),
validator: (String value) {
if (value == null || value.isEmpty) {
return 'Please enter a username';
}
updateField(value, 'username');
return null;
},
),
TextFormField(
obscureText: true,
enableSuggestions: false,
autocorrect: false,
decoration: const InputDecoration(
hintText: 'Enter your password',
labelText: 'Password'),
validator: (String value) {
if (value == null || value.isEmpty) {
return 'Please enter a password';
}
updateField(value, 'password');
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: ElevatedButton(
onPressed: () {
print('hit here');
if (_formKey.currentState.validate()) {
print('hit here two');
sendHome();
print(userData);
// if API responds with proper token
// API call to login
}
},
child: Text('Submit'),
),
),
],
),
)
: SignupForm(),
ElevatedButton(
onPressed: () {
setState(() {
login = !login;
loginText = loginText == 'Sign Up' ? 'Log In' : 'Sign Up';
});
},
child: Text(loginText),
)
]),
);
}
}```
I don't know if there's some sort of router that would be better and is already implemented as switching Widgets, but I haven't found anything from my own searches.
如果用户登录,您不必返回到 userCheck
小部件。相反,您可以使用 Navigator
直接转到 Home
屏幕,使从 Login
页面到 Home
页面的转换。将导航器放在用户在 Submit
按钮的 onPressed
函数中获取有效令牌的行之后:
ElevatedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
// Goes to Home screen.
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Home(),
));
}
},
child: Text('Submit'),
),