Android Kotlin中Fragment使用数据库LiveData出现类型不匹配如何解决?
问题根本原因
你定义的DAO层getObjects()方法返回值是LiveData<List<Objects>>,这是一个可观察的数据流容器,不是实际的数据列表。之前使用观察者模式时,你订阅了这个LiveData的变化,回调参数it才是LiveData包裹的实际List<Objects>数据,所以可以直接给适配器赋值。而你现在直接调用viewModel.getObjects()拿到的是LiveData容器本身,自然和适配器要求的List<Objects>类型不匹配。
解决方案
方案1:保留数据库响应式更新能力(推荐)
如果你希望数据库数据变化时,当前选择数据库作为数据源的情况下列表能自动更新,就用这种方案:
首先在ViewModel中新增控制数据源切换的变量,以及合并后的列表LiveData:
class ObjectsViewModel(private val repository: ObjectsRepository): ViewModel() { // 控制是否使用数据库数据源的标记 val useDbSource = MutableLiveData<Boolean>() // 非持久化的临时数据源,从Fragment传入 val otherObjects = MutableLiveData<List<Objects>>() // 自动根据标记切换数据源 val displayObjects = Transformations.switchMap(useDbSource) { useDb -> if (useDb) repository.getObjects() else otherObjects } }
然后在Fragment中统一观察displayObjects来更新适配器,需要切换数据源时只需要修改useDbSource的值即可:
// Fragment的onViewCreated中统一观察 viewModel.displayObjects.observe(viewLifecycleOwner) { adapter.objects = it adapter.notifyDataSetChanged() } // 需要切换数据源时调用 if (condition) { viewModel.useDbSource.value = true } else { viewModel.otherObjects.value = otherObjects viewModel.useDbSource.value = false }
这种方式不需要你手动管理数据更新,只要数据源变化,列表会自动刷新。
方案2:仅单次获取数据库数据
如果你不需要监听数据库的后续变化,只是需要在切换时拿一次当前的数据库数据,就给DAO新增直接返回列表的挂起方法:
@Dao interface ObjectsDao { @Query("SELECT * FROM objects") fun getObjects(): LiveData<List<Objects>> // 新增单次查询方法,返回实际列表 @Query("SELECT * FROM objects") suspend fun getObjectsOnce(): List<Objects> }
然后Repository和ViewModel层同步新增对应方法:
// Repository class ObjectsRepository (private val db: ObjectsDatabase) { fun getObjects() = db.getObjectsDao().getObjects() suspend fun getObjectsOnce() = db.getObjectsDao().getObjectsOnce() } // ViewModel class ObjectsViewModel(private val repository: ObjectsRepository): ViewModel() { fun getObjects() = repository.getObjects() suspend fun getObjectsOnce() = repository.getObjectsOnce() }
在Fragment切换数据源时用协程调用:
lifecycleScope.launch { adapter.objects = if (condition) viewModel.getObjectsOnce() else otherObjects adapter.notifyDataSetChanged() }
内容的提问来源于stack exchange,提问作者Taqras
相关产品推荐
相关产品推荐

