Flutter:防止在键盘隐藏时调用 TextField 的 onChange(后按)
Flutter: Prevent to call onChange of TextField when Keyboard hide (Back Press)
我正在研究 Flutter,根据搜索参数调用 API。
我所做的是:
- 使用 TextField
创建的搜索框
- onChange 那个 TextField,我调用了从服务器获取数据的方法。
- 显示列表的ListView
问题:当我使用返回键完成搜索后隐藏键盘时,它再次请求获取数据。
你可以查看video以获得更好的解释:
这是我的代码:
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。
注意:如果我使用键盘上的done键隐藏键盘,它不会调用API并顺利隐藏。
已编辑:
我现在离线测试过,离线也能调用。它在关闭键盘时调用 onChange 事件。
跟踪最后搜索的文本并比较从 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 方法的事情做出反应
为什么会这样?
发生这种情况是因为您正在撰写的文本范围已更改,当您在两个用 space 分隔的单词之间更改光标时,当您单击第一个 onChange 时,将会发生此事件被调用,当你点击另一个词 onChange 回调将被调用时再次调用
您可以在第 2242 行看到 EditableTextState 和 _formatAndSetValue 函数的 SDK 源代码,此函数负责调用 onChange 回调,为此它接收一个 TextEditingValue 对象,该对象包含有关 TextField 中发生的更改的信息例如,它包含文本 属性,它指的是更改或选择后的 TextFild 文本 属性,它指的是用户选择的字符,还有一个 TextRange 属性,它指的是范围仍在编写的文本,在 _formatAndSetValue 中它正在检查调用 onChangeMethod 的条件
第一个是查看文本是否与之前的 TextFiled 文本不同,第二个是检查 Composing 范围是否与之前的 Composing 范围不同
so when you click on a word in the text field or event empty text
field and keyboard opens up the composing range is changed to that
word or section which you click and when you close the keyboard
composing range is changed -1,-1 which means it is empty
我最近遇到了这个问题,当时我不得不在 3 个字母后调用 API,但是当我一个一个地删除它时,即使它调用的是 API,
所以我的解决方案:
我将长度条件放在 textEditingController 而不是 onChanged Value
if(searchController.text.trim().isNotEmpty && searchController.text.trim().length>=3
)
{
//调用你的API
}
我正在研究 Flutter,根据搜索参数调用 API。
我所做的是:
- 使用 TextField 创建的搜索框
- onChange 那个 TextField,我调用了从服务器获取数据的方法。
- 显示列表的ListView
问题:当我使用返回键完成搜索后隐藏键盘时,它再次请求获取数据。
你可以查看video以获得更好的解释:
这是我的代码:
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。
注意:如果我使用键盘上的done键隐藏键盘,它不会调用API并顺利隐藏。
已编辑:
我现在离线测试过,离线也能调用。它在关闭键盘时调用 onChange 事件。
跟踪最后搜索的文本并比较从 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 方法的事情做出反应
为什么会这样?
发生这种情况是因为您正在撰写的文本范围已更改,当您在两个用 space 分隔的单词之间更改光标时,当您单击第一个 onChange 时,将会发生此事件被调用,当你点击另一个词 onChange 回调将被调用时再次调用
您可以在第 2242 行看到 EditableTextState 和 _formatAndSetValue 函数的 SDK 源代码,此函数负责调用 onChange 回调,为此它接收一个 TextEditingValue 对象,该对象包含有关 TextField 中发生的更改的信息例如,它包含文本 属性,它指的是更改或选择后的 TextFild 文本 属性,它指的是用户选择的字符,还有一个 TextRange 属性,它指的是范围仍在编写的文本,在 _formatAndSetValue 中它正在检查调用 onChangeMethod 的条件 第一个是查看文本是否与之前的 TextFiled 文本不同,第二个是检查 Composing 范围是否与之前的 Composing 范围不同
so when you click on a word in the text field or event empty text field and keyboard opens up the composing range is changed to that word or section which you click and when you close the keyboard composing range is changed -1,-1 which means it is empty
我最近遇到了这个问题,当时我不得不在 3 个字母后调用 API,但是当我一个一个地删除它时,即使它调用的是 API,
所以我的解决方案:
我将长度条件放在 textEditingController 而不是 onChanged Value
if(searchController.text.trim().isNotEmpty && searchController.text.trim().length>=3 ) { //调用你的API }