如何在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
相关产品推荐
相关产品推荐

