【问题标题】:Delay call to onQueryTextChange() in SearchView.OnQueryTextListener with SearchView使用 SearchView 延迟调用 SearchView.OnQueryTextListener 中的 onQueryTextChange()
【发布时间】:2015-07-14 20:58:19
【问题描述】:

在我的应用程序中使用SearchView

无论如何我可以延迟调用 onQueryTextChange() 方法。就像,当用户输入一个字符序列时,他必须等待这个方法被调用。

这种等待应该取决于输入的字符数,但在方法被点击之前需要稍作停顿。

我想暂停一下,因为当用户在搜索视图中键入内容时,将向服务器发出带有字符串的请求以请求匹配的数据,然后我将根据建议填充我的 ListView。

活动信息(如果需要):
实现SearchView.OnQueryTextListener

    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView)MenuItemCompat.getActionView(searchItem);
    searchView.setOnQueryTextListener(this);

【问题讨论】:

  • 不,你为什么需要那个?
  • 您可以使用 TimerTask 来延迟过滤您的列表。把过滤的代码放在定时器里面。但是我不建议延迟搜索。
  • @pskink 在用户输入 SearchView 时从服务器获取数据。不能在每次输入字符时都发出请求,而应该暂停。
  • @Skynet 请详细说明,为什么不推荐一个 TimerTask?
  • 看看 Play 商店是如何做到的 - 超级快?

标签: android searchview


【解决方案1】:

要延迟对服务器的调用,请在 onQueryTextChange 方法中使用以下代码,变量 mQueryString 和 mHandler 必须是类变量。 还要检查 mHandler!=null

@Override
public boolean onQueryTextChange(String searchTerm) {
    mQueryString = searchTerm;
    mHandler.removeCallbacksAndMessages(null);

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
           //Put your call to the server here (with mQueryString)
        }
    }, 300);
    return true;
}

【讨论】:

  • 谢谢你。
【解决方案2】:

使用 SearchView 在 SearchView.OnQueryTextListener 中延迟调用 onQueryTextChange()

private long delay = 2000; 
private long editTextLastWord = 0;
privaste  SearchView searchView;
Handler handler = new Handler();

private Runnable runnable = new Runnable() {
    public void run() {
        if (System.currentTimeMillis() > (editTextLastWord + delay - 500)) {

          perFormTask();
        }
    }
};
 searchView=(SearchView) findViewById(R.id.searchView);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
 if (s.length() > 2) {              
          editTextLastWord = System.currentTimeMillis();
          handler.postDelayed(runnable, delay);
        } else {

        }
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
  handler.removeCallbacks(runnable);
            }
        });

【讨论】:

    【解决方案3】:

    这应该对您有所帮助,您的班级需要实现“SearchView.OnQueryTextListener”,并且必须在您的班级中声明“cntr”

    这已经为普通用户打字而闪烁,如果您想等待更多,只需提高“waitingTime”即可。

    请求应该在“onFinish”里面

        private int waitingTime = 200;
        private CountDownTimer cntr;
    
        @Override
        public boolean onQueryTextChange(String newText) {
        if(cntr != null){
            cntr.cancel();
        }
        cntr = new CountDownTimer(waitingTime, 500) {
    
            public void onTick(long millisUntilFinished) {
                Log.d("TIME","seconds remaining: " + millisUntilFinished / 1000);
            }
    
            public void onFinish() {
                Log.d("FINISHED","DONE");
            }
        };
        cntr.start();
        return false;
    }
    

    【讨论】:

    • 这应该是公认的答案,因为第一个答案对调用方法“运行”两次具有不良影响
    【解决方案4】:

    您可以像这样使用 Kotlin 协程。 声明倒计时作业

    private lateinit var textChangeCountDownJob: Job
    

    然后onQueryTextChange:

        override fun onQueryTextChange(newText: String): Boolean {
    
            if(::textChangeCountDownJob.isInitialized)
                textChangeCountDownJob.cancel()
    
            textChangeCountDownJob = launch(UI) {
                delay(800)
            }
    
            return false
        }
    

    【讨论】:

    • 我认为使用协程更简单更有效。但是launch 方法来自哪个包?
    • @nadinnnnnne textChangeCountDownJob = lifecycleScope.launch { .. }
    【解决方案5】:

    1) 创建抽象类:

    public abstract class DelayedOnQueryTextListener implements SearchView.OnQueryTextListener {
    
        private Handler handler = new Handler();
        private Runnable runnable;
    
        @Override
        public boolean onQueryTextSubmit(String s) {
            return false;
        }
    
        @Override
        public boolean onQueryTextChange(String s) {
            handler.removeCallbacks(runnable);
            runnable = () -> onDelayerQueryTextChange(s);
            handler.postDelayed(runnable, 400);
            return true;
        }
    
        public abstract void onDelayerQueryTextChange(String query);
    }
    

    2) 设置如下:

    searchView.setOnQueryTextListener(new DelayedOnQueryTextListener() {
        @Override
        public void onDelayerQueryTextChange(String query) {
            // Handle query
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      相关资源
      最近更新 更多