BottomSheetFragment更新后Home Fragment不实时刷新问题(Room+ViewModel)
问题解决:修改任务后Home Fragment无法实时更新
核心问题是TaskViewModel的update方法执行数据库更新后,没有重新加载数据并更新LiveData,导致Home Fragment的观察者收不到变更通知。另外还有几处潜在问题需要修正,以下是具体解决方案:
1. 修复TaskViewModel的update方法
在update方法执行完数据库更新后,调用loadAllTask()重新加载数据并更新notesList,和delete方法保持一致:
fun update(task: Task) = viewModelScope.launch{ tRepo.update(task) loadAllTask() // 新增这行,触发LiveData更新 }
2. 替换自定义CoroutineScope为viewModelScope
ViewModel中不要手动创建CoroutineScope,应该使用Jetpack提供的viewModelScope,它会在ViewModel销毁时自动取消协程,避免内存泄漏。修改所有协程调用:
@HiltViewModel class TaskViewModel @Inject constructor(private var tRepo: TaskRepository) : ViewModel() { val notesList = MutableLiveData<List<Task>>() init { loadAllTask() } fun loadAllTask() { viewModelScope.launch { notesList.postValue(tRepo.getAllTask()) } } fun delete(task: Task) = viewModelScope.launch { tRepo.delete(task) loadAllTask() } fun update(task: Task) = viewModelScope.launch{ tRepo.update(task) loadAllTask() } fun search(searchText : String) = viewModelScope.launch { notesList.value = tRepo.search(searchText) } }
3. 修复Home Fragment中ViewModel的初始化
当前Home Fragment里的viewmodel变量只声明未初始化,会导致空指针异常。使用Hilt的by viewModels()完成初始化:
@AndroidEntryPoint class HomeFragment : Fragment() { private lateinit var binding: FragmentHomeBinding // 修改为Hilt支持的ViewModel初始化方式 private val viewmodel: TaskViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // ... 其他代码保持不变 } }
4. 可选优化:用DiffUtil提升RecyclerView性能
当前Adapter的updateList用notifyDataSetChanged()会刷新整个列表,性能较差。可以改用DiffUtil只更新变化的条目:
// 新增DiffUtil回调类 class TaskDiffCallback(private val oldList: List<Task>, private val newList: List<Task>) : DiffUtil.Callback() { override fun getOldListSize() = oldList.size override fun getNewListSize() = newList.size override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition].id == newList[newItemPosition].id } override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] } } // 修改Adapter的updateList方法 fun updateList(newList : List<Task>){ val diffCallback = TaskDiffCallback(this.list, newList) val diffResult = DiffUtil.calculateDiff(diffCallback) this.list = newList diffResult.dispatchUpdatesTo(this) }
完成以上修改后,修改任务后Home Fragment会实时收到数据更新通知,RecyclerView自动刷新显示最新内容。
内容的提问来源于stack exchange,提问作者Murad Axundov
相关产品推荐
相关产品推荐

