2016-01-22 75 views
3

什么是“节流”onQueryTextChange的最佳方式,以便我的performSearch()方法每秒只调用一次,而不是每次用户输入时调用?在SearchView中调节onQueryTextChange

public boolean onQueryTextChange(final String newText) { 
    if (newText.length() > 3) { 
     // throttle to call performSearch once every second 
     performSearch(nextText); 
    } 
    return false; 
} 

回答

1

我结束了类似于下面的解决方案。那样它应该每半秒发射一次。

 public boolean onQueryTextChange(final String newText) { 

      if (newText.length() > 3) { 

       if (canRun) { 
        canRun = false; 
        handler.postDelayed(new Runnable() { 
         @Override 
         public void run() { 

          canRun = true; 
          handleLocationSearch(newText); 
         } 
        }, 500); 
       } 
      } 

      return false; 
     } 
2

您可以通过RxJava轻松实现。此外,您将需要RxAndroidRxBinding(但如果您使用的是RxJava,您可能已经在您的项目中拥有它们)。

RxTextView.textChangeEvents(yourEditText) 
      .debounce(1, TimeUnit.SECONDS) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(performSearch()); 

Here Kaushik Gopal的完整示例。

+0

谢谢!不过,我现在并没有真正引入RxJava。它可以在本地完成吗? – aherrick

+0

不幸的是,我不知道这个问题的任何常见清洁解决方案。我完全可以通过Handler延迟或Timer和TimerTasks来实现。 –

8

建立在aherrick的代码上,我有一个更好的解决方案。每次查询文本发生更改时,请声明一个可运行变量并清除处理程序上的回调队列,而不是使用布尔值“canRun”。这是我最后使用的代码:

@Override 
public boolean onQueryTextChange(final String newText) { 
    searchText = newText; 

    // Remove all previous callbacks. 
    handler.removeCallbacks(runnable); 

    runnable = new Runnable() { 
     @Override 
     public void run() { 
      // Your code here. 
     } 
    }; 
    handler.postDelayed(runnable, 500); 

    return false; 
} 
3

我想出使用RxJava的解决方案,特别是debounce运营商。

杰克沃顿商学院的得心应手RxBinding,我们也会有这样:

RxSearchView.queryTextChanges(searchView) 
     .debounce(1, TimeUnit.SECONDS) // stream will go down after 1 second inactivity of user 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(new Consumer<CharSequence>() { 
      @Override 
      public void accept(@NonNull CharSequence charSequence) throws Exception { 
       // perform necessary operation with `charSequence` 
      } 
     });