使用领域和LiveData。将LiveData <RealmResults <CustomModelObject >>转换为LiveData <List <CustomModelObject >>

Pau*_*aul 3 android realm android-livedata

我正在尝试将Realm与包括LiveData在内的Android体系结构组件一起使用。

我一直在关注Google的《应用程序体系结构指南》:

https://developer.android.com/topic/libraries/architecture/guide.html

用空间代替房间。

我正在使用的一切:

LiveData<RealmResults<CustomModelObject>>
Run Code Online (Sandbox Code Playgroud)

从我的存储库层,一直到ViewModel到View。

我想这可能是更好的只有有更多的泛型类型来从仓库回来,LiveData<List<CustomModelObject>>而不是LiveData<RealmResults<CustomModelObject>>

这是我遇到问题的代码段:

@NonNull
@Override
protected LiveData<List<CustomModelObject>> loadFromDb() {
    return Transformations.switchMap(customModelObjectsDao.getCustomModelObjects(),
        new Function<RealmResults<CustomModelObject>, LiveData<List<CustomModelObject>>>() {
        @Override
        public LiveData<List<CustomModelObject>> apply(RealmResults<CustomModelObject> data) {
            if (data == null) {
                return AbsentLiveData.create();
            } else {
                return customModelObjectsDao.getCustomModelObjects();
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

customModelObjectsDao.getCustomModelObjects()目前返回LiveData<RealmResults<Inspiration>>

我想将其转换为LiveData<List<Inspiration>>

我尝试过各种方法Transformations.map,但都Transformations.switchMap没有成功,我想我已经盯着它太久了:)

我在正确的道路上还是缺少明显的东西?

任何帮助是极大的赞赏。

谢谢,保罗。

更新

道:

public RealmLiveData<CustomModelObject> getCustomModelObjects() {
    return asLiveData(realm.where(CustomModelObject.class).findAllAsync());
}
Run Code Online (Sandbox Code Playgroud)

asLiveData Impl:

fun <T: RealmModel> RealmResults<T>.asLiveData() = RealmLiveData<T>(this)
fun Realm.CustomModelObjectsDao(): CustomModelObjectsDao = CustomModelObjectsDao(this)
Run Code Online (Sandbox Code Playgroud)

更新2

public class RealmLiveData<T> extends LiveData<RealmResults<T>> {

private RealmResults<T> results;

private final RealmChangeListener<RealmResults<T>> listener = new RealmChangeListener<RealmResults<T>>() {
    @Override
    public void onChange(RealmResults<T> results) {
        setValue(results);
    }
};

public RealmLiveData(RealmResults<T> realmResults) {
    results = realmResults;
}

@Override
protected void onActive() {
    results.addChangeListener(listener);
}

@Override
protected void onInactive() {
    results.removeChangeListener(listener);
}
}
Run Code Online (Sandbox Code Playgroud)

Epi*_*rce 5

在你的情况下,更换LiveData<RealmResults<T>LiveData<List<T>>就足以解决你的问题。

但是,我建议尝试RealmLiveResults使用官方示例中可用的类:

/**
 * This class represents a RealmResults wrapped inside a LiveData.
 *
 * Realm will always keep the RealmResults up-to-date whenever a change occurs on any thread,
 * and when that happens, the observer will be notified.
 *
 * The RealmResults will be observed until it is invalidated - meaning all local Realm instances on this thread are closed.
 *
 * @param <T> the type of the RealmModel
 */
public class LiveRealmResults<T extends RealmModel> extends LiveData<List<T>> {
    private final RealmResults<T> results;

    // The listener will notify the observers whenever a change occurs.
    // The results are modified in change. This could be expanded to also return the change set in a pair.
    private OrderedRealmCollectionChangeListener<RealmResults<T>> listener = new OrderedRealmCollectionChangeListener<RealmResults<T>>() {
        @Override
        public void onChange(@NonNull RealmResults<T> results, @Nullable OrderedCollectionChangeSet changeSet) {
            LiveRealmResults.this.setValue(results);
        }
    };

    @MainThread
    public LiveRealmResults(@NonNull RealmResults<T> results) {
        //noinspection ConstantConditions
        if (results == null) {
            throw new IllegalArgumentException("Results cannot be null!");
        }
        if (!results.isValid()) {
            throw new IllegalArgumentException("The provided RealmResults is no longer valid, the Realm instance it belongs to is closed. It can no longer be observed for changes.");
        }
        this.results = results;
        if (results.isLoaded()) {
            // we should not notify observers when results aren't ready yet (async query).
            // however, synchronous query should be set explicitly.
            setValue(results);
        }
    }

    // We should start observing and stop observing, depending on whether we have observers.

    /**
     * Starts observing the RealmResults, if it is still valid.
     */
    @Override
    protected void onActive() {
        super.onActive();
        if (results.isValid()) { // invalidated results can no longer be observed.
            results.addChangeListener(listener);
        }
    }

    /**
     * Stops observing the RealmResults.
     */
    @Override
    protected void onInactive() {
        super.onInactive();
        if (results.isValid()) {
            results.removeChangeListener(listener);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您dao可以公开LiveData<List<T>>,并且Transformations.map()应该可以工作。