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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:23:22