先观测LiveData后调用LivePagedListBuilder时Observe回调未触发问题
问题根因分析
- 第一种写法失效的核心原因:你在
onViewCreated阶段观察的searchDetails是ViewModel初始化时的初始实例,而后续在onProcessSearch方法中调用LivePagedListBuilder.build()生成了全新的LiveData实例,并且直接覆盖了原有的searchDetails变量。原有的旧LiveData实例从来没有被赋值过数据,自然不会触发观察回调。 - 第二种写法生效的原因:你先调用
onProcessSearch完成了新LiveData实例的赋值,再对这个新生成的LiveData实例执行observe操作,后续新实例加载到PagedList数据时,自然能通知到观察者。
符合官方规范的修复方案
官方推荐在onViewCreated中一次性注册观察的写法,你只需要修改ViewModel的实现,不要每次搜索都新建LiveData实例,而是用可触发搜索的LiveData做转换即可,示例修改如下:
ViewModel 改造代码
// 定义搜索触发信号LiveData private val searchTrigger = MutableLiveData<Array<String?>>() // 用switchMap转换,每次搜索触发时生成新的PagedList LiveData,不需要替换外部实例 val searchDetails = searchTrigger.switchMap { searchValue -> val pagedListConfig = PagedList.Config.Builder() .setEnablePlaceholders(true) .setPageSize(PageSize).build() LivePagedListBuilder(PageKeyedSearchDataFactory(viewModelScope, searchValue), pagedListConfig).build() } fun onProcessSearch(searchValue: Array<String?>?) { // 只需要给触发信号赋值,不需要重新创建searchDetails实例 searchValue?.let { searchTrigger.postValue(it) } }
Fragment 代码(保留官方推荐的观察时机)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { viewModel?.searchDetails?.observe(viewLifecycleOwner) { populateSearchResults(it) } } override fun onClick(view: View) { if (view.id == R.id.match_patient_search_button) { viewModel?.onProcessSearch(searchValue) GlobalHelper.hideKeyBoard(view) } }
内容的提问来源于stack exchange,提问作者PrashanthR
相关产品推荐
相关产品推荐

