Android RecyclerView MVVM架构下应在哪调用notifyDataSetChanged更新Adapter
你完全不需要使用广播接收器,也不是必须依赖LiveData实现。针对你描述的「数据源仅单次初始化、无后续更新」的场景,以下两种实现方案均符合MVVM规范:
方案1:协程直接等待加载结果(最简洁)
利用视图生命周期绑定的协程Scope,直接触发ViewModel的数据加载逻辑,加载完成后直接更新Adapter,全程不需要观察者。
调整MyViewModel.kt
将加载方法改为公开的挂起方法,加载完成后直接返回数据集:
private val _myItems = mutableListOf<Item>() val myItems: List<Item> = _myItems // 修改为公开挂起方法 suspend fun loadItems(): List<Item> { val remoteItems = itemsRepository.getSomeItems() _myItems.addAll(remoteItems) return remoteItems }
调整MyFragment.kt
在onViewCreated中用viewLifecycleOwner.lifecycleScope执行加载逻辑:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //... recyclerView.adapter = myItemAdapter viewLifecycleOwner.lifecycleScope.launch { // 等待数据加载完成 val loadedItems = viewModel.loadItems() // 更新Adapter myItemAdapter.dataList = loadedItems myItemAdapter.notifyDataSetChanged() // 若使用ListAdapter可直接调用myItemAdapter.submitList(loadedItems) } }
该方案不会产生内存泄漏,协程会在Fragment视图销毁时自动取消,也符合ViewModel不持有视图引用的规范。
方案2:单次事件流通知
如果你的加载逻辑需要在ViewModel内部自动触发,不需要Fragment主动调用,可使用MutableSharedFlow实现单次事件通知,比LiveData更轻量:
调整MyViewModel.kt
private val _myItems = mutableListOf<Item>() val myItems: List<Item> = _myItems // 定义单次通知流 private val _loadFinishEvent = MutableSharedFlow<Unit>(replay = 0) val loadFinishEvent: SharedFlow<Unit> = _loadFinishEvent private fun someMethod() { viewModelScope.launch { _myItems.addAll(itemsRepository.getSomeItems()) // 加载完成发送通知 _loadFinishEvent.emit(Unit) } }
调整MyFragment.kt
在onViewCreated中监听单次加载完成事件:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //... recyclerView.adapter = myItemAdapter viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.loadFinishEvent.collect { // 收到加载完成通知,更新Adapter myItemAdapter.dataList = viewModel.myItems myItemAdapter.notifyDataSetChanged() } } } }
补充说明
如果没有特殊限制,即使用LiveData封装数据源也不会产生多余的性能开销,仅发送一次数据的场景下LiveData的重量可以忽略,你可以根据自己的编码习惯选择方案。
内容的提问来源于stack exchange,提问作者SaPropper
相关产品推荐
相关产品推荐

