我正在研究 Flutter,基于搜索参数调用 API。
我所做的是:
问题:当我使用后退键完成搜索后隐藏键盘时,它再次请求获取数据。
您可以查看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。
注意:如果我使用键盘上的完成键隐藏键盘,它不会调用 API 并顺利隐藏。
因为我现在已经离线测试,它也在离线调用。它在关闭键盘时调用 onChange 事件。
答案 0 :(得分:4)
跟踪上次搜索的文本并比较从 onChange 回调到达的 newText,如果它们不同,则可以执行 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 回调将被调用
您可以在第 2242 行看到 EditableTextState 和 _formatAndSetValue 函数的 SDK 源代码,该函数负责调用 onChange 回调,为此它接收一个 TextEditingValue 对象,该对象包含有关 TextField 中发生的更改的信息,例如它包含 text 属性,它指的是更改后的 TextFild 文本,或者是指用户选择的字符的选择属性,以及一个 TextRange 属性,它指的是仍在编写的文本范围,并且在 _formatAndSetValue 中它正在检查调用 onChangeMethod 的条件 第一个是查看文本是否与之前的 TextFiled 文本不同,第二个是检查 Composing 范围是否与之前的 Composing 范围不同
<块引用>因此,当您单击文本字段中的单词或事件为空文本时 字段和键盘打开组合范围更改为 当您关闭键盘时单击的单词或部分 组合范围更改为 -1,-1 表示为空
答案 1 :(得分:0)
我最近遇到了这个问题,当我不得不在 3 个字母后调用 API 时,即使它正在调用 API,但当我一个一个地删除它时,
所以我的解决方案:
我将长度条件放在 textEditingController 而不是 onChanged 值
if(searchController.text.trim().isNotEmpty && searchController.text.trim().length>=3 ) { //调用你的API }