You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:15:04