首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将LiveData转换为MutableLiveData

将LiveData转换为MutableLiveData
EN

Stack Overflow用户
提问于 2018-06-20 08:42:58
回答 5查看 23.4K关注 0票数 17

显然,Room无法处理MutableLiveData,我们必须坚持使用LiveData,因为它返回以下错误:

代码语言:javascript
复制
error: Not sure how to convert a Cursor to this method's return type

我用这种方式在DB助手中创建了一个“自定义”MutableLiveData:

代码语言:javascript
复制
class ProfileRepository @Inject internal constructor(private val profileDao: ProfileDao): ProfileRepo{

    override fun insertProfile(profile: Profile){
        profileDao.insertProfile(profile)
    }

    val mutableLiveData by lazy { MutableProfileLiveData() }
    override fun loadMutableProfileLiveData(): MutableLiveData<Profile> = mutableLiveData

    inner class MutableProfileLiveData: MutableLiveData<Profile>(){

        override fun postValue(value: Profile?) {
            value?.let { insertProfile(it) }
            super.postValue(value)
        }

        override fun setValue(value: Profile?) {
            value?.let { insertProfile(it) }
            super.setValue(value)
        }

        override fun getValue(): Profile? {
            return profileDao.loadProfileLiveData().getValue()
        }
    }
}

这样,我可以从DB获得更新,并可以保存Profile对象,但不能修改属性。

例如:mutableLiveData.value = Profile()可以工作。mutableLiveData.value.userName = "name"会调用getValue()而不是postValue(),而不会工作。

有人找到解决办法了吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-06-20 09:54:46

请说我疯了,但是AFAIK没有理由对您从DAO接收到的对象使用MutableLiveData。

其思想是您可以通过LiveData<List<T>>公开一个对象。

代码语言:javascript
复制
@Dao
public interface ProfileDao {
    @Query("SELECT * FROM PROFILE")
    LiveData<List<Profile>> getProfiles();
}

现在你可以观察到:

代码语言:javascript
复制
profilesLiveData.observe(this, (profiles) -> {
    if(profiles == null) return;

    // you now have access to profiles, can even save them to the side and stuff
    this.profiles = profiles;
});

因此,如果您想要使这个活动数据“发出一个新数据并修改它”,那么您需要将概要文件插入到数据库中。写入将重新评估此查询,一旦将新的配置文件值写入db,就会发出该查询。

代码语言:javascript
复制
dao.insert(profile); // this will make LiveData emit again

所以没有理由使用getValue/setValue,只需将其写入数据库即可。

票数 12
EN

Stack Overflow用户

发布于 2019-08-09 09:47:12

如果你真的需要的话,你可以用调停人的把戏。

In ViewModel

代码语言:javascript
复制
 val sourceProduct: LiveData<Product>() = repository.productFromDao()
 val product = MutableLiveData<Product>()
    
 val mediator = MediatorLiveData<Unit>()

 init {
      mediator.addSource(sourceProduct, { product.value = it })
 }

片段/活性

代码语言:javascript
复制
observe(mediator, {})
observe(product, { /* handle product */ })
票数 10
EN

Stack Overflow用户

发布于 2021-12-09 14:13:19

LiveData转化为MutableLiveData的Kotlin扩展

代码语言:javascript
复制
/**
 * Transforms a [LiveData] into [MutableLiveData]
 *
 * @param T type
 * @return [MutableLiveData] emitting the same values
 */
fun <T> LiveData<T>.toMutableLiveData(): MutableLiveData<T> {
    val mediatorLiveData = MediatorLiveData<T>()
    mediatorLiveData.addSource(this) {
        mediatorLiveData.value = it
    }
    return mediatorLiveData
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50943919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档