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

Android中ViewModel LiveData Emit异常,如何复用LiveDataScope实现下拉刷新?

解决方案

要实现下拉刷新并复用原有数据获取逻辑,核心是让LiveData能够重新触发数据请求。可以通过触发器LiveData+switchMap的方式改造ViewModel,同时在Fragment中关联下拉刷新事件。

1. 改造ViewModel代码

把原有数据获取逻辑抽离,通过一个可触发的refreshTrigger来控制LiveData重新执行请求:

class DistanceViewModel(private val distanceRepository: DistanceRepository) : ViewModel() {
    private val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
        // 处理异常,比如打印日志或通知UI
        throwable.printStackTrace()
    }

    // 刷新触发器:发送Unit事件即可触发重新请求
    private val refreshTrigger = MutableLiveData<Unit>()

    // 通过switchMap绑定触发器,每次触发都重新创建LiveData执行请求
    val distanceLiveData: LiveData<List<Distance>> = refreshTrigger.switchMap {
        liveData(coroutineExceptionHandler) {
            val distanceList = distanceRepository.getDistanceList()
            emit(distanceList)
        }
    }

    init {
        // 初始加载数据
        triggerRefresh()
    }

    // 对外暴露的刷新方法,供Fragment调用
    fun triggerRefresh() {
        refreshTrigger.value = Unit
        // 若需避免主线程阻塞,也可使用refreshTrigger.postValue(Unit)
    }
}

2. 修改Fragment代码

在下拉刷新监听中调用ViewModel的刷新方法,并在数据更新后关闭刷新状态:

// 初始化仅需设置一次Adapter,无需每次数据更新重复设置
binding.recyclerViewDistance.adapter = adapter

// 观察LiveData接收数据更新
distanceViewModel.distanceLiveData.observe(viewLifecycleOwner) { distanceList ->
    distanceList?.let {
        adapter.submitList(it)
        // 数据更新完成后关闭下拉刷新动画
        binding.swipeRefreshLayoutDistance.isRefreshing = false
    }
}

// 设置下拉刷新监听
binding.swipeRefreshLayoutDistance.setOnRefreshListener {
    // 触发ViewModel重新请求数据
    distanceViewModel.triggerRefresh()
}

关键说明

  • switchMap会监听refreshTrigger的变化,每次refreshTrigger发送新值,就会重新执行liveData构建器内的代码,实现数据重新请求,完全复用原有数据获取逻辑。
  • 异常处理沿用你原有的coroutineExceptionHandler,保证异常捕获逻辑一致。
  • 修正了你Fragment代码的冗余问题:原代码重复调用adapter.submitList(it)且每次都设置recyclerView.adapter,初始化时设置一次Adapter即可,数据更新仅需调用submitList。

内容的提问来源于stack exchange,提问作者Nima Khalili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:22:25