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

如何在Android项目中实现MVVM架构解决RecyclerView更新问题?

分步实现LiveData+ViewModel解决RecyclerView更新问题

1. 添加必要依赖

在app模块的build.gradle(Module级别)中加入ViewModel和LiveData的依赖:

dependencies {
    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
    // Lifecycle KTX(简化生命周期操作,可选)
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
}

2. 创建ShowViewModel

ViewModel负责持有UI相关数据,生命周期与Fragment/Activity绑定,不会因配置变更销毁:

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class ShowViewModel(private val repository: ShowRepository) : ViewModel() {
    // 私有可变LiveData,仅ViewModel内部可修改
    private val _showList = MutableLiveData<List<ShowModel>>()
    // 对外暴露不可变LiveData,供UI层观察
    val showList: LiveData<List<ShowModel>> = _showList

    // 初始化时自动加载数据
    init {
        loadShows()
    }

    // 从仓库加载数据,用协程处理异步操作
    fun loadShows() {
        viewModelScope.launch {
            // 调用仓库原有方法获取初始数据
            val initialShows = repository.getAllShows()
            _showList.value = initialShows
            // 给Firebase添加实时监听,数据变化时自动更新LiveData
            repository.addShowsChangeListener { updatedShows ->
                _showList.postValue(updatedShows)
            }
        }
    }
}

3. 改造ShowRepository

让仓库支持实时监听Firebase数据变化,新增数据时自动通知ViewModel:

import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import kotlinx.coroutines.tasks.await

class ShowRepository {
    private val firebaseDatabase = FirebaseDatabase.getInstance()
    private val showsRef = firebaseDatabase.getReference("shows")

    // 原有一次性获取数据的方法
    suspend fun getAllShows(): List<ShowModel> {
        val snapshot = showsRef.get().await()
        return snapshot.children.mapNotNull { it.getValue(ShowModel::class.java) }
    }

    // 添加实时数据变化监听
    fun addShowsChangeListener(onShowsUpdated: (List<ShowModel>) -> Unit) {
        showsRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                val updatedShows = snapshot.children.mapNotNull { it.getValue(ShowModel::class.java) }
                onShowsUpdated(updatedShows)
            }

            override fun onCancelled(error: DatabaseError) {
                error.toException().printStackTrace()
            }
        })
    }

    // 其他Activity调用的新增数据方法
    suspend fun addShow(showModel: ShowModel) {
        showsRef.push().setValue(showModel).await()
    }
}

4. 修改HomeFragment,观察ViewModel数据

在Fragment中获取ViewModel,监听LiveData变化并更新Adapter:

import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager

class HomeFragment : Fragment() {
    private lateinit var showViewModel: ShowViewModel
    private lateinit var showAdapter: ShowAdapter
    // 保存筛选排序后的列表副本
    private var filteredShows = listOf<ShowModel>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 初始化Adapter
        showAdapter = ShowAdapter(filteredShows)
        recyclerView.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = showAdapter
        }

        // 创建ViewModel实例
        showViewModel = ViewModelProvider(this) {
            ShowViewModel(ShowRepository())
        }.get(ShowViewModel::class.java)

        // 观察LiveData,数据变化时更新UI
        showViewModel.showList.observe(viewLifecycleOwner) { allShows ->
            // 执行你的筛选排序逻辑
            filteredShows = filterAndSortShows(allShows)
            // 通知Adapter更新数据
            showAdapter.updateList(filteredShows)
        }
    }

    // 自定义筛选排序逻辑(示例)
    private fun filterAndSortShows(allShows: List<ShowModel>): List<ShowModel> {
        return allShows.filter { it.isActive }
            .sortedBy { it.name }
    }
}

5. 改造ShowAdapter,支持列表更新

给Adapter添加替换列表的方法,方便接收新数据:

import androidx.recyclerview.widget.RecyclerView

class ShowAdapter(private var shows: List<ShowModel>) : RecyclerView.Adapter<ShowAdapter.ShowViewHolder>() {

    // 更新列表的方法
    fun updateList(newShows: List<ShowModel>) {
        shows = newShows
        notifyDataSetChanged() // 新手先使用这个,后续可优化为DiffUtil提升性能
    }

    // ViewHolder及其他原有逻辑保持不变
    class ShowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        // 绑定数据逻辑
    }

    override fun getItemCount() = shows.size
}

6. 自动更新逻辑说明

当你在其他Activity调用ShowRepository的addShow()方法新增数据时,Firebase的addValueEventListener会实时监听到数据变化,自动触发ViewModel的LiveData更新。HomeFragment的观察者收到新数据后,会重新执行筛选排序,并通知Adapter刷新列表,RecyclerView就能自动显示新增内容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:05:23