Flutter TextFormField 控件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter TextFormField 控件相关的知识,希望对你有一定的参考价值。
参考技术A 一个FormField包含TextField,它将TextField小部件包装在FormField中。表单(From)使一次进行保存、重置或验证多个字段变得更容易。要在没有表单(From)的情况下使用,请将GlobalKey传递给构造函数,并使用GlobalKey.currentState保存或重置表单字段。
指定控制器时,initialValue必须为null(默认值)。如果controller为null,那么TextEditingController将被自动构造,其文本将初始化为initalValue或空字符串。如果这个FormField是滚动容器的一部分,该容器懒加载它的子对象,比如ListView或CustomScrollView,那么应该指定一个控制器。控制器的生命周期应该由滚动容器的有状态小部件祖先来管理。
Flutter 2 - 设置自动完成 TextFormField 的初始值
【中文标题】Flutter 2 - 设置自动完成 TextFormField 的初始值【英文标题】:Flutter 2 - Set initial value of an Autocomplete TextFormField 【发布时间】:2021-06-19 23:56:27 【问题描述】:我不能使用TextEditingController
,因为TextFormField
使用Autocomplete
fieldViewBuilder
TextEditingController
Autocomplete(
optionsBuilder: (TextEditingValue textEditingValue)
if (textEditingValue.text == '') return [];
return this
.productNames
.where((Map<String, dynamic> option)
return option['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
);
,
fieldViewBuilder: (context, textEditingController,
focusNode, onFieldSubmitted) =>
TextFormField(
controller: textEditingController,//uses fieldViewBuilder TextEditingController
focusNode: focusNode,
),
),
【问题讨论】:
【参考方案1】:编辑
我刚刚意识到您正在使用 TextFormField,它有一个名为 initialValue 的参数。如果您不需要文本编辑控制器,这个答案应该可以工作
fieldViewBuilder: (context, textEditingController,
focusNode, onFieldSubmitted) =>
TextFormField(
focusNode: focusNode,
initialValue:"Your initial Value",
),
或者如果你正在使用你的控制器试试
fieldViewBuilder: (context, textEditingController,
focusNode, onFieldSubmitted) =>
TextFormField(
controller: textEditingController..text="Initial Value",
focusNode: focusNode,
),
原始答案
您为什么不使用该文本编辑控制器本身。代码将是这样的
Autocomplete(
optionsBuilder: (TextEditingValue textEditingValue)
if (textEditingValue.text == '') return [];
return this
.productNames
.where((Map<String, dynamic> option)
return option['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
);
,
fieldViewBuilder: (context, textEditingController,
focusNode, onFieldSubmitted)
textEditingController.text = "Your initial text";// You can use the next snip of code if you dont want the initial text to come when you use setState(());
return TextFormField(
controller: textEditingController,//uses fieldViewBuilder TextEditingController
focusNode: focusNode,
),
),
如果您正在使用 setState 并且上面的代码段不断将文本替换为初始文本,请执行类似的操作
Autocomplete(
optionsBuilder: (TextEditingValue textEditingValue)
if (textEditingValue.text == '') return [];
return this
.productNames
.where((Map<String, dynamic> option)
return option['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
);
,
fieldViewBuilder: (context, textEditingController,
focusNode, onFieldSubmitted)
textEditingController.text = textEditingController.text == ""? "Inital Text":textEditingController.text;// You can use the next snip of code if you dont want the initial text to come when you use setState(());
return TextFormField(
controller: textEditingController,//uses fieldViewBuilder TextEditingController
focusNode: focusNode,
),
),
最后一个解决方案不太优雅,但很有效。如果我找到更好的解决方案,我会告诉你。您甚至可以将此 textEditingController 分配给在顶部声明的全局变量,并从代码中的任何位置访问它。而不是检查文本是否为空,而是在每次 setState 时增加一个新变量的值,如果值为 == 0,则可以设置初始文本
【讨论】:
这是我目前正在使用的.. 但是每次我更改初始值并调用setState()
。我收到以下错误。它确实有效,但由于这个错误,我认为它不是正确的方法。 在为 TextEditingController 发送通知时引发以下断言: 在构建期间调用了 setState() 或 markNeedsBuild()。
我不完全确定为什么会针对您的项目抛出此错误,我将不得不查看代码文件,但调用它的原因是因为您调用 setState() 方法过早没有完成构建。该错误无关紧要,因为构建会立即完成,因此可以运行更改
我已经从 Autocomplete()
中注释掉了 textEditingController.text = "Your initial text";
。当我调用setState()
时,它不会抛出任何错误
我猜更改文本将重建文本字段,这将导致无限循环。尝试在顶部设置一个计数器变量并将其设置为 0。然后在构建器中,检查计数器变量是否为 0。如果为 0,则设置初始文本(它可能会重建它,但只能重建一次)并将其添加到计数器变量。也许在延迟的异步函数中分配初始文本
@ibrahimxcool 我刚刚添加了 2 种新方法。如果您不需要控制器,请尝试第一个,如果您需要控制器,请尝试第二个【参考方案2】:
AutoComplete 对此有一个命名参数 initialValue
。
Autocomplete<AutocompletePrediction>(
initialValue: const TextEditingValue(text: "Initial value"),
fieldViewBuilder: ...
...
)
【讨论】:
【参考方案3】:这是我为TextFormField
找到的解决方案。确保控制器在帧结束时更新。
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted)
SchedulerBinding.instance?.addPostFrameCallback((_) // <--- this part
var initialValue = someValueThatGotUpdatedDuringBuild;
fieldTextEditingController.text = initialValue;
);
return TextFormField(...);
...
【讨论】:
@thenoobslayer,见上文,如果您仍有问题,可能会解决您的问题。 这对我有用,但在较新版本的 Flutter 中它应该是 `WidgetsBinding.instance.addPostFrameCallback((_) `以上是关于Flutter TextFormField 控件的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 键盘隐藏时TextFormField变为空白