【问题标题】:Flutter 2 - Set initial value of an Autocomplete TextFormFieldFlutter 2 - 设置自动完成 TextFormField 的初始值
【发布时间】:2021-06-19 23:56:27
【问题描述】:

我不能使用TextEditingController,因为TextFormField使用AutocompletefieldViewBuilderTextEditingController

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,
                ),
              ),

【问题讨论】:

    标签: flutter dart flutter2.0


    【解决方案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((_) { `
      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 2020-06-14
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      相关资源
      最近更新 更多