Android SearchView的onQueryTextChange搭配ObservableOnSubscribe不生效如何解决
问题修复方案
问题原因分析
- 核心原因是使用了
distinct()操作符:该操作符会记录整个流生命周期内所有发射过的字符串,后续出现重复值会直接过滤。你删除搜索框字符时,产生的字符串(比如之前输入过的短文本、空字符串)大多已经发射过,会被distinct()直接拦截,不会触发下游的搜索逻辑。 - 次要有空值安全隐患:代码中直接用
!!强转可空的newText/query,如果系统回调传入null会直接触发空指针崩溃,可能导致后续事件无法继续接收。 - 小概率原因:如果其他位置也给
binding.searchView设置了OnQueryTextListener,会覆盖这里的监听设置,导致回调不触发。
修复方案
1. 替换去重操作符
把distinct()换成distinctUntilChanged(),该操作符仅对比当前值和上一个发射的值是否相同,只要和上一次输入不一样就会下发,完全符合搜索输入的场景,不会拦截回删产生的历史字符串。
2. 增加空值处理
对回调传入的可空字符串做兜底处理,避免空指针。
3. 确认无其他监听覆盖
检查全局代码,确保没有其他地方重复给该SearchView设置OnQueryTextListener。
修复后代码
compositeDisposable.add(Observable.create(ObservableOnSubscribe<String> { subscriber -> binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextChange(newText: String?): Boolean { // 空值兜底为空字符串 subscriber.onNext(newText.orEmpty()) return false } override fun onQueryTextSubmit(query: String?): Boolean { subscriber.onNext(query.orEmpty()) return false } }) }) .debounce(250, TimeUnit.MILLISECONDS) // 替换为仅相邻去重 .distinctUntilChanged() .subscribe { text -> val pagerPos = binding.streamsPager.currentItem val currentFragment = activity?.supportFragmentManager?.findFragmentByTag("f${pagerAdapter.getItemId(pagerPos)}") // 替换为安全强转避免崩溃 (currentFragment as? StreamFragment)?.onSearchHolder?.onSearch(text) } )
内容的提问来源于stack exchange,提问作者Yana Glad
相关产品推荐
相关产品推荐

