Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在SearchView中限制onQueryTextChange_Java_Android_Search_Searchview_Android Search - Fatal编程技术网

Java 在SearchView中限制onQueryTextChange

Java 在SearchView中限制onQueryTextChange,java,android,search,searchview,android-search,Java,Android,Search,Searchview,Android Search,“限制”onQueryTextChange的最佳方法是什么,这样我的performSearch()方法每秒只调用一次,而不是每次用户键入时都调用一次 public boolean onQueryTextChange(final String newText) { if (newText.length() > 3) { // throttle to call performSearch once every second performSearch(n

“限制”onQueryTextChange的最佳方法是什么,这样我的
performSearch()
方法每秒只调用一次,而不是每次用户键入时都调用一次

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

你可以很容易地做到这一点。此外,您还需要和(但如果您使用的是RxJava,那么您的项目中可能已经有了它们)


Kaushik Gopal的完整示例。

我最终得到了一个类似于下面的解决方案。那样的话,它应该每半秒发射一次

        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;
        }

基于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;
}

我已经想出了一个解决方案,使用,特别是它的运营商

有了杰克·沃顿的手边,我们就有了:

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`
            }
        });
RxSearchView.queryTextChanges(searchView)
.debounce(1,TimeUnit.SECONDS)//用户不活动1秒后,流将停止
.observeOn(AndroidSchedulers.mainThread())
.订阅(新消费者){
@凌驾
public void accept(@NonNull CharSequence CharSequence)引发异常{
//使用“charSequence”执行必要的操作`
}
});

如果您正在使用Kotlin和协同程序,您可以执行以下操作:

var queryTextChangedJob: Job? = null

...

fun onQueryTextChange(query: String) {

    queryTextChangedJob?.cancel()
    
    queryTextChangedJob = launch(Dispatchers.Main) {
        delay(500)
        performSearch(query)
    }
}
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
        }
    });

对于Korlin

coroutineScope.launch(Dispatchers.Main){}
的情况下,您可能会遇到问题
Suspend函数“…”应该仅从一个coroutine或另一个Suspend函数调用

我找到了下面的方法

private var queryTextChangedJob: Job? = null
private lateinit var searchText: String
接下来不要忘记使用
实现“androidx.lifecycle:lifecycle runtime ktx:2.3.0-alpha05”

如果要在ViewModel内部使用
启动
,请使用
实现“androidx.lifecycle:lifecycle ViewModel ktx:2.3.0-alpha05”


谢谢然而,在这一点上,我对引入RxJava并不感兴趣。它可以在本地完成吗?不幸的是,我不知道这个问题的任何通用清洁解决方案。我肯定可以通过处理程序延迟或计时器和计时器任务来实现。这是一个错误的解决方案。请参阅此解决方案缺少取消。如果您不再需要观察查询文本更改,您应该记住从处理程序中删除回调。路由是前进的方向!谢谢你的回答。
private var queryTextChangedJob: Job? = null
private lateinit var searchText: String
override fun onQueryTextChange(newText: String?): Boolean {

    val text = newText ?: return false
    searchText = text

    queryTextChangedJob?.cancel()
    queryTextChangedJob = lifecycleScope.launch(Dispatchers.Main) {
        println("async work started...")
        delay(2000)
        doSearch()
        println("async work done!")
    }

    return false
}
queryTextChangedJob = viewModelScope.launch(Dispatchers.Main) {
        //...
}