Android 在无状态小部件中使用TextFormField在Flatter中非常困难
我试图在无状态小部件中使用TextFormField和ScopedModel来处理其中的文本,并面临以下各种问题Android 在无状态小部件中使用TextFormField在Flatter中非常困难,android,ios,flutter,flutter-layout,Android,Ios,Flutter,Flutter Layout,我试图在无状态小部件中使用TextFormField和ScopedModel来处理其中的文本,并面临以下各种问题 我尝试使用控制器来控制字段,但每次我输入一些文本并按键盘上的“完成”键时,文本都会被清除。不知道为什么 若我移除控制器,文本将保留在字段中,但如何从字段中获取文本会产生新的问题。我用回调函数解决了这个问题 但事实证明,只有当我们单击键盘上的“完成”按钮时,才会调用onfildSubmitted。若我在字段中输入文本,而不是单击“确定”,而是单击另一个字段,则不会调用回调,并且我将无法
class LoginPageStateless extends StatelessWidget {
final loginUsernameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
body: ScopedModelDescendant<AccountModel>(
builder: (context, child, model) {
return Form(
//key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Email id',
hintText: 'johndoe@ipropal.com',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
),
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Password',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
obscureText: true,
),
],
),
);
},
),
);
}
}
类loginpagestaless扩展了无状态小部件{
最终loginUsernameController=TextEditingController();
@凌驾
小部件构建(构建上下文){
返回脚手架(
resizeToAvoidBottomPadding:true,
正文:ScopedModelSchendant(
生成器:(上下文、子对象、模型){
报税表(
//键:_formKey,
子:列(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
TextFormField(
样式:TextStyle(fontSize:15.0),
装饰:输入装饰(
labelText:“电子邮件id”,
hintText:'johndoe@ipropal.com',
),
控制器:loginUsernameController,
onFieldSubmitted:model.updateLoginUsernameText,
),
TextFormField(
样式:TextStyle(fontSize:15.0),
装饰:输入装饰(
labelText:“密码”,
),
控制器:loginUsernameController,
onFieldSubmitted:model.updateLoginUsernameText,
蒙昧文字:对,
),
],
),
);
},
),
);
}
}
您不能也不应该使用无状态
小部件来存储长期变量
问题是,这正是你想要的TextEditingController
是一个类实例,应该在渲染之间保留。但通过将其存储到无状态小部件中
,您基本上可以在每次更新后重新创建它
您应该将小部件转换为有状态的。然后将该控制器移动到
状态
部分到目前为止,我还没有使用TextFormField
,我一直使用TextField()
,因为它简单灵活。我在使用Redux
和无状态小部件时遇到了类似的问题,因为我在顶级存储中只有一个真实来源。因此,我必须在ViewModel
中创建一些回调,然后将该回调分配给文本字段callbackonChanged
,该字段接受字符串参数
CustomTextWidgetWrapper(
onChangedCallback: viewModel.onChanged
),
在小部件中包装的TextField
(不提供更多详细信息):
在视图模型中,我获取字符串并将其分派到中央存储器,以便在其他小部件中重用,就像一个按钮,它获取数据并发送到服务器
static ViewModel fromStore(Store<AppState> store) {
return new ViewModel(
onChanged: (String textFieldText) {
// I call dispatch or an API here if I want
store.dispatch(new CallAPI(params: textFieldText);
来自商店的静态视图模型(商店){
返回新的ViewModel(
onChanged:(字符串文本字段文本){
//如果需要,我可以在这里调用dispatch或API
store.dispatch(新的调用API(参数:textFieldText);
如果我将控制器移动到作用域模型中怎么办?它也应该可以工作。虽然这不一定有意义,但将作用域模型与有状态小部件一起使用有意义吗?混合使用有状态小部件和作用域模型没有错。动画和控制器非常适合有状态小部件。这对在有状态小部件中使用控制器,因为这是它的预期用途。为了保持该特定小部件的状态。如果您没有在小部件外部使用此控制器,则不需要将其放入ScopedModel中,因为ScopedModel通常用于共享变量。
static ViewModel fromStore(Store<AppState> store) {
return new ViewModel(
onChanged: (String textFieldText) {
// I call dispatch or an API here if I want
store.dispatch(new CallAPI(params: textFieldText);