Skip to content Skip to sidebar Skip to footer

Merge Multiple Realmlist´s And Sort Resulting List?

I just started using Realm in my current android app and so far it is great. Unfortunately I´ve encountered a problem: In my app the user can add different kind of entries (What

Solution 1:

Thanks @EpicPandaForce

I solved it exactly the way you described it and it works like a charm - now I even have the real-time functionality and no need to refresh the data manually, Nice :)

In case anybody faces the same problem I post some code pieces here that show how I solved it in code.

publicclassEntryextendsRealmObject {
    privatestaticfinalintENTRY_MEAL=0;
    privatestaticfinalintENTRY_DRINK=1;
    privatestaticfinalintENTRY_SYMPTOM=2;
    privatestaticfinalintENTRY_MEDICINE=3;

    /** The tag describes what kind of entry it represents */privateint tag;

    /* Only one of these can be set, according to what this entry represents. */@Nullableprivate MealEntry mealEntry;
    @Nullableprivate DrinkEntry drinkEntry;
    @Nullableprivate SymptomEntry symptomEntry;
    @Nullableprivate MedicineEntry medicineEntry;

    /** The time value this entry was created at *//** Format: hours + minutes * 60 */privateint time;

    publicintgetTime() {
        return time;
    }

/* Can only be accessed from within the 'data' package */voidsetTime(int time) {
        this.time = time;
    }

/**
     * Creates a new entry object in the realm database and tags it as 'MEAL'
     *
     * @param realm not null
     * @param mealEntry the {@link MealEntry} object to map this entry to, not null
     *
     * @return the newly created entry
     */static Entry createEntryAsMeal(@NonNullfinal Realm realm, @NonNullfinal MealEntry mealEntry) {
        if(realm == null) {
            thrownewIllegalArgumentException("'realm' may not be null");
        }
        if(mealEntry == null) {
            thrownewIllegalArgumentException("'mealEntry' may not be null");
        }

        Entryentry= realm.createObject(Entry.class);
        entry.tag = ENTRY_MEAL;
        entry.mealEntry = mealEntry;
        return entry;
        }

/* Same methods for other tag types ... */

In MealEntry.class:

publicclassMealEntryextendsRealmObject {

    @PrimaryKey@Requiredprivate String id;

    @Requiredprivate String title;

    /** The entry objects this meal-entry is added to */
    Entry entry;

    /** This time value describes when the user consumed this meal **/privateint time;
// other fields/**
* Creates a new MealEntry object in the realm.
 * <p>
 *     Note: It is important to use this factory method for creating {@link MealEntry} objects in realm.
 *     Under the hood, a {@link Entry} object is created for every MealEntry and linked to it.
 * </p>
 *
 * @param realm not null
 *
 * @return new MealEntry object which has been added to the <code>realm</code>
 */publicstatic MealEntry createInRealm(@NonNull Realm realm) {
    if(realm == null) {
        thrownewIllegalArgumentException("'realm' may not be null");
    }

    MealEntrymealEntry= realm.createObject(MealEntry.class, UUID.randomUUID().toString());
    mealEntry.entry = Entry.createEntryAsMeal(realm, mealEntry);
    return mealEntry;
}

The 'time' field exists in the Entry.class and MealEntry.class so if the latter one changes the Entry must be updated accordingly:

/**
     * Sets the time value for the <code>mealEntry</code> to the specified value.
     * <p>
     *     Note: This method is necessary in order to sync the new time value with the underlying
     *     {@link Entry} object that is connected with the <code>mealEntry</code>.
     * </p>
     *
     * @param mealEntry the {@link MealEntry} object to set the time for, not null
     *
     * @param time the new time value, must be in range of [0, 24*60] because of the format: hours*60 + minutes
     *
     */publicstaticvoidsetTimeForMealEntry(@NonNull MealEntry mealEntry, @IntRange(from=0, to=24*60)int time) {
        if(mealEntry == null) {
            thrownewIllegalArgumentException("'mealEntry' may not be null");
        }

        mealEntry.setTime(time);

        Entryentry= mealEntry.entry;
        if(entry == null) {
            thrownewIllegalStateException("'mealEntry' contains no object of type 'Entry'! Something went wrong on creation of the 'mealEntry'");
        }

        /* Syncs the entries time value with the time value for this MealEntry. *//* That´s important for sorting a list of all entries. */
        entry.setTime(time);
    }

Note: I could have stored only the ID of the corresponding Entry object inside the MealEntry and vice-versa for the Entry object store an ID to the corresponding MealEntry object. However I don´t know what a difference in perfomance this makes so I just went with the above approach. One reason for the other approach though would be that I wouldn´t have to store the 'time' field twice, once in the Entry.class and once in the MealEntry.class, because in the Entry.class I could just get the time value by finding the corresponding MealEntry object by its ID and then get the time.

Post a Comment for "Merge Multiple Realmlist´s And Sort Resulting List?"