Flutter 颤振2-设置自动完成TextFormField的初始值

Flutter 颤振2-设置自动完成TextFormField的初始值,flutter,dart,flutter2.0,Flutter,Dart,Flutter2.0,我不能使用TextEditingController,因为TextFormField使用AutocompletefieldViewBuilderTextEditingController Autocomplete( optionsBuilder: (TextEditingValue textEditingValue) { if (textEditingValue.text == '') return [];

我不能使用
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,
                ),
              ),
自动完成(
选项生成器:(TextEditingValue TextEditingValue){
如果(textEditingValue.text='')返回[];
还这个
.productNames
.where((映射选项){
返回选项['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder:(上下文、文本编辑控制器、,
focusNode,onFieldSubmitted)=>
TextFormField(
控制器:textEditingController,//使用fieldViewBuilder textEditingController
focusNode:focusNode,
),
),
编辑

我刚刚意识到您使用的是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,
                ),
               }
              ),
自动完成(
选项生成器:(TextEditingValue TextEditingValue){
如果(textEditingValue.text='')返回[];
还这个
.productNames
.where((映射选项){
返回选项['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder:(上下文、文本编辑控制器、,
focusNode,onfield(已提交){
text editingcontroller.text=“您的初始文本”;//如果您不希望在使用setState((){})时出现初始文本,则可以使用下一段代码;
返回TextFormField(
控制器:textEditingController,//使用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,
                ),
               }
              ),
自动完成(
选项生成器:(TextEditingValue TextEditingValue){
如果(textEditingValue.text='')返回[];
还这个
.productNames
.where((映射选项){
返回选项['ar']
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder:(上下文、文本编辑控制器、,
focusNode,onfield(已提交){
textEditingController.text=textEditingController.text==“”?“初始文本”:textEditingController.text;//如果不希望在使用setState((){})时出现初始文本,则可以使用下一段代码;
返回TextFormField(
控制器:textEditingController,//使用fieldViewBuilder textEditingController
focusNode:focusNode,
),
}
),

最后一个解决方案不太优雅,但很有效。如果我找到更好的解决方案,我会告诉你的。您甚至可以将此textEditingController分配给顶部声明的全局变量,并从代码中的任何位置访问它。而不是检查文本是否为空,而是每次设置state时增加一个新变量的值,如果值==0,则可以设置初始文本,我认为@Siddharth Agrawal的答案可能会有一些改进

再添加一个平面,如:

bool init=false;


这是我为
TextFormField
找到的解决方案。确保在帧结束时更新控制器

fieldViewBuilder:(构建上下文上下文,
TextEditingController字段TextEditingController,
FocusNode字段FocusNode,
作废(已提交){

SchedulerBinding.instance?.addPostFrameCallback((){//这是我当前使用的..但是每次我更改初始值并调用
setState()时
。我收到以下错误..它确实起作用,但由于此错误,我认为这不是正确的方法。在为TextEditingController发送通知时引发了以下断言:setState()或markNeedsBuild()在生成过程中调用。我不确定为什么会针对您的项目引发此错误,我必须查看代码文件,但调用此错误的原因是因为您正在调用setState()方法太早,生成尚未完成。错误无关紧要,因为生成已立即完成,因此更改可以运行。我已从
自动完成()
中注释掉
textEditingController.text=“您的初始文本”
。当我调用
setState()时
它不会引发任何错误我猜更改文本将重建文本字段,这将形成一个无限循环。尝试在顶部设置一个计数器变量,并将其设置为0。然后在生成器中,检查计数器变量是否为0。如果为0,则设置初始文本(它可能会重建它,但只能重建一次)并在计数器变量中添加一个。可能在延迟异步中分配初始文本function@ibrahimxcool我刚刚添加了两种新方法。如果您不需要控制器,请尝试第一种方法,如果您需要控制器,请尝试第二种方法controller@thenoobslayer,请参见上文,如果您
 fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted){
      if(!init){
           String initValue="Inital Text";
           textEditingController.value= TextEditingValue( text: initValue,selection:TextSelection.collapsed(offset:initValue.length));  
           init=true;
      }
       return TextFormField(                             
              controller: textEditingController,
              focusNode: focusNode,
                  );
  }