如何让 TextWatcher 在执行某些操作之前等待一段时间

Posted

技术标签:

【中文标题】如何让 TextWatcher 在执行某些操作之前等待一段时间【英文标题】:How to make TextWatcher wait for some time before doing some action 【发布时间】:2013-01-17 14:40:51 【问题描述】:

我有一个EditText 来过滤它下面ListView 中的项目,通常可能包含1000 多个项目。 TextWatcher 是:

txt_itemSearch.addTextChangedListener(new TextWatcher() 

public void onTextChanged(CharSequence s, int start, int before, int count) 
    fillItemList();

public void afterTextChanged(Editable s) 


public void beforeTextChanged(CharSequence s, int start, int count,
                int after) 

);

这里的问题是,随着用户输入的每个字母,列表都会刷新,正是这种重复的列表更新导致 UI 变慢。

如何让TextWatcher 等待 1-2 秒,如果 2 秒后没有更多输入,则过滤列表。有什么建议吗?

【问题讨论】:

有什么建议吗? - 使用适配器的getFilter() 方法过滤ListView 好的,但是过滤有点复杂。我还有几个复选框和其他要过滤的参数,所以我唯一的选择是通过 SQLite 查询来获取它。 【参考方案1】:

如果没有更多输入,如何让 textWatcher 等待 1-2 秒 2 秒后发生,然后过滤列表。

正如我在评论中已经说过的,您应该考虑使用适配器的getFilter() 方法。因为这可能不合适(如你所说)尝试实现适配器的过滤器用于在过滤器输入之间取消的相同机制。

private Handler mHandler = new Handler();

public void afterTextChanged(Editable s) 
      mHandler.removeCallbacks(mFilterTask); 
      mHandler.postDelayed(mFilterTask, 2000);

filterTask 在哪里:

Runnable mFilterTask = new Runnable() 

     @Override
     public void run() 
          fillItemList();
            

【讨论】:

当我现在检查 LogCat 时,我注意到虽然处理只在 2 秒后发生,但 Runnable 运行了很多次。例如,如果我输入“sof”,fillItemList 会运行 3 次 - 用于“s”、“so”和“sof”。我以为 Handler.removeCallbacks 会处理它,但它没有。 @rbH 你确定吗?你打字够快吗? 糟糕!。我的错。我将 mFilterTask 放在 afterTextChanged 中,因此每次都会创建一个新的可运行对象。现在比牛奶还滑:) 谢谢【参考方案2】:

使用RxBinding:

RxTextView.textChanges(edittext)
            .skipInitialValue()
            .debounce(TIME_TO_WAIT, TimeUnit.MILLISECONDS)
            .subscribe(
               //do the thing
            )

【讨论】:

以上是关于如何让 TextWatcher 在执行某些操作之前等待一段时间的主要内容,如果未能解决你的问题,请参考以下文章

当TextWatcher存在时退格/删除时按EditText光标位置

Android 文本监听接口TextWatcher详解

如何让 Selenium/Ruby 机器人在执行操作之前等待?

如何持续监控某些网站并定期执行操作

如何在 iOS 中的 prepareForSegue 之前执行按钮按下操作?

如何在Node.js中检测键序列以执行某些操作