Представьте себе следующий сценарий:
Приложение имеет TextFormField
, где пользователь вводит большую строку.
Поле формы будетпрокрутите автоматически вправо по мере ввода пользователем, что и ожидается.Пока все хорошо.
TextFormField
также имеет FocusNode
, который будет отклонен, когда пользователь завершит издание, таким образом, вызывая onFieldSubmitted()
и запрашивая новый фокусв другое поле, что-то вроде:
onFieldSubmitted: (_) => FocusScope.of(context).requestFocus(_someOtherNode);
Теперь я хочу, чтобы потерявший фокус
TextFormField
прокручивал назад к началу, а не оставлял курсор в конце, имеет смысл, верно?Оказывается, это действительно возможно, изменив
value
его
TextEditingController
_firsFieldController.value = TextEditingValue(
text: _firstFieldController.text,
selection: TextSelection.collapsed(offset: 0),
composing: TextRange.collapsed(0)));
Все это имеет смысл и работает, до определенного момента.Вот когда начинается проблема.Изменение значения
TextEditingController
вызовет
ValueNotifier
для всех его слушателей, но, поскольку это синхронный процесс, если я немедленно запросю фокус на новом узле, курсор не будет обновлен до его начала, потому что на самом деле требуетсясфокусируйтесь на
TextFormField
, который оживляет назад.
TL; DR
Это не будет работать, потому что фокус на новый узел будетбыть установленным перед установкой курсора в начале первого
onFieldSubmitted: (_) {
_firstFieldController.value = TextEditingValue(
text: _firstFieldController.text,
selection: TextSelection.collapsed(offset: 0),
composing: TextRange.collapsed(0));
FocusScope.of(context).requestFocus(_passwordFocusNode);
}
Добавление небольшой задержки перед запросом нового фокуса, чтобы позволить перестроить слушателей, заставит его работать, но кажется совершенно неправильным
Future.delayed(Duration(milliseconds: 200))
.then((_) => FocusScope.of(context).requestFocus(_newFocusNode));