web-dev-qa-db-fra.com

Convertir LiveData en MutableLiveData

Apparemment, Room n’est pas capable de gérer MutableLiveData et nous devons nous en tenir à LiveData car il renvoie l’erreur suivante:

error: Not sure how to convert a Cursor to this method's return type

J'ai créé un MutableLiveData "personnalisé" dans mon assistant de base de données de cette manière:

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()
        }
    }
}

De cette façon, j'obtiens les mises à jour de la base de données et je peux enregistrer l'objet Profile mais je ne peux pas modifier les attributs.

Par exemple: mutableLiveData.value = Profile() fonctionnerait .mutableLiveData.value.userName = "name" appellerait getValue() à la place de postValue() et ne fonctionnerait pas.

Quelqu'un a-t-il trouvé une solution à cela?

6
kike

Appelez-moi fou, mais autant que je sache, il n'y a aucune raison d'utiliser un MutableLiveData pour l'objet que vous avez reçu de la DAO.

L'idée est que vous pouvez exposer un objet via LiveData<List<T>> 

@Dao
public interface ProfileDao {
    @Query("SELECT * FROM PROFILE")
    LiveData<List<Profile>> getProfiles();
}

Maintenant, vous pouvez les observer:

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;
});

Donc, si vous voulez que ces données en direct "émettent de nouvelles données et les modifient", vous devez alors insérer le profil dans la base de données. L'écriture réévaluera cette requête et elle sera émise une fois que la nouvelle valeur de profil aura été écrite dans la base de données.

dao.insert(profile); // this will make LiveData emit again

Il n’ya donc aucune raison d’utiliser getValue/setValue, il suffit d’écrire sur votre base de données.

6
EpicPandaForce

Puisque Room ne prend pas en charge MutableLiveData et ne prend en charge que LiveData, votre approche consistant à créer un wrapper est la meilleure approche à laquelle je puisse penser. Il sera compliqué pour Google de supporter MutableLiveData car les méthodes setValue et postValue sont public. Où comme pour LiveData ils sont protected qui donne plus de contrôle.

0
Sagar