如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?
Posted
技术标签:
【中文标题】如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?【英文标题】:How to set Initial value to a TextFormField on value received from previous screen in Flutter? 【发布时间】:2019-12-05 21:07:03 【问题描述】:在我的 react native 项目中,我在一页中有一个数据列表。然后单击列表中的每张卡片,我通过传递按下的卡片的值(如下面的代码)转到它们的详细信息页面-
Navigator.pushNamed(ctxt, '/DetailsNotes', arguments: _allNotes[index]);
之后,在下一个屏幕中,我会收到构建函数中的值,如下所示-
final ModelAllNotes args = ModalRoute.of(context).settings.arguments;
在这个屏幕中,我有两个 TextFormField 并在构建函数中初始化它们,如下所示-
final title = TextFormField(
controller: _textFieldControllerTitle,
keyboardType: TextInputType.emailAddress,
autofocus: false,
maxLength: 100,
decoration: InputDecoration(
hintText: 'Title',
labelText: 'Title',
icon: Icon(selectedIcons),
contentPadding: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 20.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10.0)),
),
validator: (value)
if (value.isEmpty)
return 'Enter some text';
return null;
,
onSaved: (String value)
this._data.title = value;
,
);
我还声明了 controlller 来处理 TextFormField 的文本更改和保存问题,如下所示-
TextEditingController _textFieldControllerTitle = TextEditingController();
那么,现在的问题是——
我想从 args 变量中接收到的值中获得 TextFormField 的初始值,然后允许用户编辑 TextformFields。但是,每当我对每个 TextFormField 使用 initialValue 属性时,它都不起作用。
我需要一个解决方案来从 args(来自上一个屏幕)接收到值,然后最初在我的 TextFromField 中显示它们并保持它们可编辑。
【问题讨论】:
【参考方案1】:一种选择是使用TextEditingController.fromValue(...)
:
TextFormField(
controller: TextEditingController.fromValue(
TextEditingValue(
text: arg,
selection: TextSelection.collapsed(
offset: arg.length,
),
),
),
),
您可以通过连接各种侦听器和诸如此类的东西来检索或/和操作值,从而使其更复杂/更有用。
为了查看它的实际效果,我在下面添加了一个最小的可运行示例。您的案例可能需要更多代码(也许dispose
和更强大的offset
处理),因为它仅用于说明目的。
import 'package:flutter/material.dart';
void main()
runApp(Editable());
class Editable extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
initialRoute: '/',
routes:
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
,
);
class FirstScreen extends StatelessWidget
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(title: Text('First Screen')),
body: Center(
child: RaisedButton(
child: Text('To editable screen'),
onPressed: ()
Navigator.pushNamed(context, '/second', arguments: 'some value');
,
),
),
);
class SecondScreen extends StatelessWidget
@override
Widget build(BuildContext context)
String value = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(title: Text("Second Screen")),
body: Center(
child: Column(
children: <Widget>[
TextFormField(
controller: TextEditingController.fromValue(
TextEditingValue(
text: value,
selection: TextSelection.collapsed(offset: value.length),
),
),
),
RaisedButton(
onPressed: ()
Navigator.pop(context);
,
child: Text('Back'),
),
],
),
),
);
【讨论】:
【参考方案2】:试试这个:
class ... extends State<...>
TextEditingController controller;
@override
void initState()
controller = TextEditingController();
super.initState();
@override
void didChangeDependencies()
final arg = ModalRoute.of(context).settings.arguments;
controller.text = arg;
super.didChangeDependencies();
@override
void dispose()
controller.dispose();
super.dispose();
【讨论】:
以上是关于如何在 Flutter 中从上一个屏幕收到的值上将初始值设置为 TextFormField?的主要内容,如果未能解决你的问题,请参考以下文章