M Tomczyński M Tomczyński - 1 month ago 17
Android Question

Realm - insert object into specific location

I was wondering if there's any way to manage RealmResults just as List<>. Is there a simple way to achieve adding at specific index functionality through transactions? What I mean is that I want to take item from one position and put it in other position in the database, preferably without using sort which requires specific field in object to sort by it. I want position to be reflected as an index at which item is positioned.

To summarize, how to do this -> realmResults.add(INDEX, object); Using realm transactions?
Also on inserts I need to put objects into first index in the database.

Answer

We talked about this on Reddit, and the solution is to explicitly add a field position, and use findAllSorted(MyObjFields.POSITION), which automatically updates whenever a new element is added.

To actually reorder the data-set in an adapter, for smaller datasets, I'd recommend creating an unmanaged copy of the result list, re-order it, and then save it back on a background thread.

List<Obj> unmanagedList = realm.copyFromRealm(results);


//...


realm.executeTransactionAsync(new Realm.Transaction() {
    public void execute(Realm realm) {
        for(int i = 0; i < unmanagedList.size(); i++) {
            Obj obj = unmanagedList.get(i);
            Obj managedObj = realm.where(Obj.class).equalTo(ObjFields.ID, obj.getId()).findFirst();
            if(managedObj != null) {
                managedObj.setPosition(i);
            }
        }
    }
});

The only edge case is that the unmanaged list doesn't auto-update if new elements are added. If you do need to handle this explicitly, then a RealmChangeListener<RealmResults<Obj>> can be used for a result set stored as a field variable.