Flutter 2 - Установить начальное значение для Autocomplete TextFormField

Я не могу использовать, потому что 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,
                ),
              ),

4 ответа

Автозаполнение имеет именованный параметр initialValueдля этого.

      Autocomplete<AutocompletePrediction>(  
    initialValue: const TextEditingValue(text: "Initial value"),  
    fieldViewBuilder: ...
    ...  
)  

РЕДАКТИРОВАТЬ

Я только что понял, что вы используете 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 глобальной переменной, объявленной вверху, и получить к ней доступ из любого места кода. И вместо того, чтобы проверять, пуст ли текст, увеличивайте значение новой переменной каждый раз, когда вы устанавливаетеState, и если значение равно == 0, вы можете установить начальный текст

Это решение, которое я нашел для TextFormField. Убедитесь, что контроллер обновлен в конце кадра.

      fieldViewBuilder: (BuildContext context,
  TextEditingController fieldTextEditingController,
  FocusNode fieldFocusNode,
  VoidCallback onFieldSubmitted) {

  SchedulerBinding.instance?.addPostFrameCallback((_) { // <--- this part
    var initialValue = someValueThatGotUpdatedDuringBuild;

    fieldTextEditingController.text = initialValue;
  });
  return TextFormField(...);
}
...

Я думаю, что это может немного улучшить ответ @Siddharth Agrawal

добавить еще одну квартиру вроде:

      bool init=false;

а также

       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,
                  );
  }
Другие вопросы по тегам