Flutter 颤振-文本字段在焦点上重建小部件
结果是你无法打开键盘。我在其他地方对这个问题做了一些挖掘,大多数问题都是当小部件是有状态的(但我的不是)。下面是Flutter 颤振-文本字段在焦点上重建小部件,flutter,textfield,Flutter,Textfield,结果是你无法打开键盘。我在其他地方对这个问题做了一些挖掘,大多数问题都是当小部件是有状态的(但我的不是)。下面是LoginWidget。我使用的是provider包,我怀疑它可能在封面下做了些什么。有人能发现我看不到的东西吗 class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { String email, password; final Global
LoginWidget
。我使用的是provider包,我怀疑它可能在封面下做了些什么。有人能发现我看不到的东西吗
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String email, password;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
return ChangeNotifierProvider<LoginModel>(
builder: (context) => LoginModel(ViewState.Idle),
child: Consumer<LoginModel>(
builder: (context, model, child) => Scaffold(
appBar: AppBar(
title: Text("Sign in"),
),
body: Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
validator: (input) {
if (input.isEmpty) {
return "Email required";
}
},
onSaved: (input) => email = input,
decoration: InputDecoration(labelText: 'Email'),
),
TextFormField(
validator: (input) {
if (input.isEmpty) {
return "Password required";
}
},
onSaved: (input) => password = input,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
model.state == ViewState.Loading
? CircularProgressIndicator()
: RaisedButton(
onPressed: () async {
if (formKey.currentState.validate()) {
formKey.currentState.save();
bool success =
await model.login(email, password);
if (success) {
// Navigator.pushNamed(context, '/');
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage()),
);
}
}
},
child: Text('Sign in'),
),
if (model.state == ViewState.Error)
Center(child: Text(model.apiErrorMessage))
],
)),
)));
}
}
类登录页面扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
字符串电子邮件,密码;
最终GlobalKey formKey=GlobalKey();
返回ChangeNotifierProvider(
生成器:(上下文)=>LoginModel(ViewState.Idle),
儿童:消费者(
生成器:(上下文、模型、子项)=>Scaffold(
appBar:appBar(
标题:文本(“登录”),
),
正文:表格(
key:formKey,
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
TextFormField(
验证器:(输入){
if(input.isEmpty){
返回“需要电子邮件”;
}
},
onSaved:(输入)=>电子邮件=输入,
装饰:输入装饰(标签文本:“电子邮件”),
),
TextFormField(
验证器:(输入){
if(input.isEmpty){
返回“需要密码”;
}
},
onSaved:(输入)=>密码=输入,
装饰:输入装饰(标签文本:“密码”),
蒙昧文字:对,
),
model.state==ViewState.load
?循环压缩机指示器()
:升起按钮(
onPressed:()异步{
if(formKey.currentState.validate()){
formKey.currentState.save();
布尔成功=
等待模式。登录(电子邮件、密码);
如果(成功){
//Navigator.pushNamed(上下文“/”);
导航器。更换(
上下文
材料路线(
生成器:(上下文)=>HomePage()),
);
}
}
},
子项:文本(“登录”),
),
if(model.state==ViewState.Error)
中心(子项:文本(model.apErrorMessage))
],
)),
)));
}
}
解决方案是将最终的GlobalKey formKey=GlobalKey()
移出构建器,使其成为静态的,但是如果您有一个“LoginPage”列表,它将使用相同的键触发小部件。
我更喜欢用消费者小部件包装父小部件。您想实现什么。。。你想禁用自动对焦吗?我根本不知道提供商软件包,所以我不会回答这个问题,但每当我看到键盘没有显示时,这是因为你试图访问的文本字段位于与主聚焦镜不同的导航器中。尝试在聚焦镜中包装表单,看看是否有帮助。在调用LoginPage
widget时,是否可以添加代码?请解释一下为什么这样做?抱歉,这里出现了新问题。为了避免不必要的小部件重建。在build方法中,通过打印类的名称来检查构建,您将得到它。