ViewModel 中的 LiveData 类型不匹配

Posted

技术标签:

【中文标题】ViewModel 中的 LiveData 类型不匹配【英文标题】:LiveData type mistmatch in ViewModel 【发布时间】:2021-01-30 13:06:10 【问题描述】:

我正在关注关于 LiveData/Room/Persistence 和存储库架构的 UDACITYs android 教程之一。

将所有代码粘合在一起后,我遇到了(我认为这是一个非常常见的问题)类型不匹配异常。

在课程示例中,创建了一个 VideosRepository,其中包含一个 LiveData 成员视频:

class VideosRepository(private val database: VideosDatabase) 

/**
 * A playlist of videos that can be shown on the screen.
 */
    val videos: LiveData<List<Video>> =
        Transformations.map(database.videoDao.getVideos()) 
            it.asDomainModel()
        

在模型中,我介绍了一个 _video 的 MutableLiveData

val playlist = videosRepository.videos //works fine

// added by me
private val _video = MutableLiveData<List<Video>>()
val video: LiveData<List<Video>> = _video

当我尝试访问 LiveData 时,这是我得到类型不匹配的地方。

fun sample()
   _video.value = videosRepository.videos //does not work and throws a Type mismatch.
   //Required: List<Video> Found: LiveData<List<Video>>

如果我尝试将所有 LiveData 填充到 ViewModel 中(意思是,只有 ViewModel 将具有 LiveData 对象声明)并将所有 LiveData 转换为纯 List 和一个函数,例如

fun getVideos(): List<Video>
    return database.videoDao.getVideo()

然后我会得到 无法访问主线程上的数据库,因为它可能会长时间锁定 UI。 我很清楚。因此,如果是这种情况,那么 LiveData 是唯一的方法。

但是我怎样才能摆脱类型不匹配。

PS。我了解 OOP 和 Java 的概念,但从未有过深入的实践经验,所以请多多包涵。

【问题讨论】:

不清楚。你到底想做什么?请提及哪些代码在哪里,例如视图模型、片段或活动等。 "_video.value = videosRepository.videos" 将其更改为 "_video.value = videosRepository.videos.value" 【参考方案1】:

_video.value 的输入是 List&lt;Video&gt;,但您分配的 videosRepository.videosLiveData&lt;List&lt;Video&gt;&gt; 您必须从 LiveData 获取List&lt;Video&gt;

_video.value = videosRepository.videos.value

【讨论】:

【参考方案2】:

videosRepository.videos的数据类型是LiveData&lt;List&lt;Video&gt;&gt;,而_video.value的数据类型是List&lt;Video&gt;,所以不能这样赋值。

试试:

val video: LiveData<List<Video>> = videosRepository.videos

然后在视图中,观察livedata对数据做你想做的事,Fragment中的例子:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
   ...
   viewModel.video.observe(viewLifecycleOwner, Observer 
      val data: List<Video> = it
      // Do something with the data such as showing it...
   )  

如果你真的想拥有MutableLiveData以防以后修改,请使用MediatorLiveData:

private val _video = MediatorLiveData<List<Video>>().apply 
   addSource(videosRepository.videos) 
      value = it
   

val video: LiveData<List<Video>> = _video

【讨论】:

以上是关于ViewModel 中的 LiveData 类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章

Android LiveData防止在观察时接收到最后一个值

抽象 ViewModel 不更新 LiveData Android MVVM

使用 Kotlin 从 Android 上 ViewModel 中的 LiveData 更新 ListView 中的元素

Android---Jetpack之LiveData

再谈协程之viewmodel-livedata难兄难弟

Android Studio 之 ROM, LiveData+ViewModel+AsyncTask+Repository