Flutter: запретить вызов onChange of TextField при скрытии клавиатуры (Back Press)
Я работаю над Flutter, API вызовов на основе параметров поиска.
Я сделал следующее:
- Поле поиска, созданное с использованием текстового поля
- onChange этого TextField, я вызвал метод для получения данных с сервера.
- ListView, отображающий список
Проблема: когда я скрываю клавиатуру после завершения поиска с помощью обратного нажатия, она снова запрашивает данные.
Вы можете посмотреть видео для лучшего объяснения:
Вот мой код:
getTextInputField() {
return Flexible(
fit: FlexFit.tight,
flex: 1,
child: TextFormField(
controller: _text,
decoration: new InputDecoration(
labelText: "Enter Area for Pincode",
fillColor: Colors.white,
errorText: _validateAgain ? 'This should not be empty!' : null,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
validator: (val) {
if (val.length == 0) {
return "This shouldn't be empty!";
} else {
return null;
}
},
onChanged: (value) {
getData();
},
keyboardType: TextInputType.streetAddress,
),
);
}
getData() {
setState(() {
if (_text.text.isNotEmpty) {
if (_text.text.length > 2) {
_validateAgain = false;
textValue = _text.text;
_apiCall = true;
_callAPIForPinCode();
}
} else
_validateAgain = true;
});
}
Как я предотвращаю повторный вызов API, когда скрываю клавиатуру с помощью обратного нажатия.
Примечание. Если я скрою клавиатуру с помощью клавиши «Готово» на клавиатуре, это не вызовет API и не скроется плавно.
Отредактировано:
Как я сейчас тестировал в автономном режиме, он тоже звонит в автономном режиме. Он вызывает событие onChange при закрытии клавиатуры.
2 ответа
отслеживать последний найденный текст и сравнивать newText, который поступает из обратного вызова onChange, и если они разные, вы можете выполнить функцию searchApi
Например :
class _PageAState extends State<PageA> {
String lastInputValue;
@override
Widget build(BuildContext context) {
return Center(
child: TextField(
onChanged: (inputValue) {
if (lastInputValue != inputValue) {
lastInputValue = inputValue;
print("New value inserted in textField $inputValue");
}
},
),
);
}
}
этот код печатается только в том случае, если значение текстового поля фактически изменено, и он не реагирует на изменения клавиатуры или другие вещи, которые могут вызвать метод onChange
Почему это происходит?
это происходит из-за того, что диапазон текста, который вы составляли, изменяется, это событие произойдет, когда вы измените курсор между двумя словами, разделенными пробелом, когда вы щелкнете по первому, onChange будет вызван и снова, когда вы нажмете на другое слово будет вызван обратный вызов onChange
вы можете увидеть исходный код SDK для EditableTextState и функции _formatAndSetValue в строке 2242, эта функция отвечает за вызов обратного вызова onChange, и для этого она получает объект TextEditingValue, который содержит информацию об изменениях, которые произошли в TextField, например, он содержит текстовое свойство который относится к тексту TextFild после изменения или свойства выбора, которое относится к тому, какие символы выбираются пользователем, а также к свойству TextRange, которое относится к диапазону текста, который все еще создается, и в _formatAndSetValue он проверяет условия для вызова onChangeMethod Первый - проверить, отличается ли текст от предыдущего текста TextFiled, а второй - проверить, отличается ли диапазон Composing от предыдущего диапазона Composing
поэтому, когда вы нажимаете слово в текстовом поле или событие, пустое текстовое поле и клавиатура открывается, диапазон составления изменяется на то слово или раздел, который вы щелкаете, и когда вы закрываете диапазон составления клавиатуры изменяется -1,-1, что означает это пусто
Недавно я столкнулся с этой проблемой, когда мне пришлось вызывать API после трех алфавитов, но когда я стираю их один за другим, даже если он вызывал API,
так что мое решение :
Я помещаю условие длины в textEditingController, а не в значение onChanged
if(searchController.text.trim().isNotEmpty && searchController.text.trim().length>=3){// вызов вашего API}