Начальное значение TextField с StreamBuilder

У меня есть TextField, визуализированный с помощью StreamBuilder, следуя шаблону BLoC со стоком и потоком.

Widget field(SignUpBloc signUpBloc) {
    return StreamBuilder(
      stream: signUpBloc.outFirstName,
      builder: (context, snapshot) {
        return TextField(
          style: TextStyle(fontSize: 15.0),
          onChanged: signUpBloc.inFirstName,
          decoration: InputDecoration(
            errorStyle: TextStyle(fontSize: 15.0),
            errorText: snapshot.error
          ),
        );
      },
    );
}

У меня вопрос: как мне установить начальное значение? Я пробовал использовать свойство StreamBuilder initialData, но в TextField нет текста.


person Mihai Neagoe    schedule 11.04.2019    source источник


Ответы (2)


TextEditingController _controller = TextEditingController(); // make a controller, 

Widget field(SignUpBloc signUpBloc) {
  return StreamBuilder(
    stream: signUpBloc.outFirstName,
    initialData: YourData, // provide initial data
    builder: (context, snapshot) {
      _controller.value = TextEditingValue(text: "${snapshot.data}"); // assign value to controller this way
      return TextField(
        controller: _controller,
        style: TextStyle(fontSize: 15.0),
        onChanged: signUpBloc.inFirstName,
        decoration: InputDecoration(
            errorStyle: TextStyle(fontSize: 15.0),
            errorText: snapshot.error
        ),
      );
    },
  );
}

Изменить: чтобы поместить курсор в конец строки, вы можете использовать

var cursorPos = _controller.selection;
if (cursorPos.start > _controller.text.length) {
  cursorPos = TextSelection.fromPosition(TextPosition(offset: _controller.text.length));
}
_controller.selection = cursorPos;

Источник

person CopsOnRoad    schedule 11.04.2019
comment
Я пробовал использовать TextEditingController, как вы показали в своем ответе, но у него есть некоторые побочные эффекты. Например, курсор всегда перемещается в крайнюю левую позицию после ввода символа. Он не отображает все введенные символы, а также отображает null, если я удаляю все символы. Трудно объяснить словами, если бы вы могли попробовать это в своей локальной среде, или, может быть, я могу обновить свой вопрос с помощью гифки. - person Mihai Neagoe; 11.04.2019
comment
Кажется, очень много кода для простого добавления начального значения в поток. Я еще не пробовал ваше обновленное решение, но уверен, что оно сработает. - person Mihai Neagoe; 12.04.2019
comment
Да, это сработает, и согласились, что кода много, вероятно, команда будет работать над добавлением немного меньшего количества строк кода. Спасибо - person CopsOnRoad; 12.04.2019

Когда вам нужно передать начальные значения, вам понадобится TextEditingController. При использовании стратегии value.copyWith нет необходимости иметь дело с курсором, а для очистки виджета вы можете передать текстовый контроллер в качестве параметра.

// Stream widget
Widget field(SignUpBloc signUpBloc, TextEditingController _txtController) {
    return StreamBuilder(
    stream: signUpBloc.outFirstName,
    builder: (context, snapshot) {
      _txtController.value =
          _txtController.value.copyWith(text: snapshot.data);
      return TextField(
          controller: _txtController,
          onChanged: signUpBloc.inFirstName;
          decoration: InputDecoration(
            errorStyle: TextStyle(fontSize: 15.0),
            errorText: snapshot.error
          ),
    });
}
person Cassio Seffrin    schedule 05.06.2020