8

我正在研究 Flutter,基于搜索参数调用 API。

我所做的是:

  • 使用TextField创建的搜索框
  • 在那个 TextField 的onChange中,我调用了从服务器获取数据的方法。
  • 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 。

注意:如果我使用键盘上的 done 键隐藏键盘,它不会调用 API 并平滑隐藏。

编辑:

由于我现在已经离线测试,它也在离线调用。它在关闭键盘时调用onChange事件。

4

2 回答 2

9

跟踪最后搜索的文本并比较从 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 回调将被调用

您可以在第 2242 行看到 EditableTextState 和 _formatAndSetValue 函数的 SDK 源代码,该函数负责调用 onChange 回调,为此它接收一个 TextEditingValue 对象,该对象包含有关 TextField 中发生的更改的信息,例如它包含 text 属性它指的是更改或选择属性后的 TextFild 文本,该属性指的是用户选择了哪些字符,还有一个 TextRange 属性,该属性指的是仍在组成的文本范围,并且在 _formatAndSetValue 中它正在检查要调用的条件onChangeMethod 第一个是查看文本是否与之前的 TextFiled 文本不同,第二个是查看撰写范围是否与之前的撰写范围不同

因此,当您单击文本字段或事件空文本字段中的一个单词并且键盘打开时,撰写范围更改为您单击的那个单词或部分,当您关闭键盘时,撰写范围更改为 -1,-1,这意味着它是空的

于 2021-04-03T11:01:15.520 回答
0

我最近遇到了这个问题,当我不得不在 3 个字母之后调用一个 API 时,但是当我一个一个地删除它时,即使它正在调用一个 API,

所以我的解决方案

我将长度条件放在textEditingController而不是onChanged Value

if(searchController.text.trim().isNotEmpty && searchController.text.trim().length>=3 ) { //调用你的 API }

于 2021-07-26T13:06:55.887 回答