androidrealmrealm-mobile-platformfastadapter

Implement RealmModel while extending AbstractItem


I was using FastAdapter cause it's fun and relieves me from writing adapter classes. Here is a class:

public class ProductsModel extends AbstractItem<ProductsModel, ProductsModel.ViewHolder> {

But recently I want to use Realm instead of SQLite. So I wanted to do this:

public class ProductsModel extends AbstractItem<ProductsModel, ProductsModel.ViewHolder> implements RealmModel {

And before any transaction I was doing this:

RealmResults<ProductsModel> productsModels = realm.where(ProductsModel.class).findAll(); // <- this line is generating the exception
if(productsModels.size() == 0){ //no product is saved, download now

}

But getting this exception:

java.lang.IllegalArgumentException: AbstractItem is not part of the schema for this Realm

Please tell me how can I use Realm with FastAdapter.


Solution

  • In case you can not extend the AbstractItem the FastAdapter allows you to simply implement the IItem interface. You will have to implement the functions you already know + the ones which would normally be implemented by the AbstractItem

    Here is a sample item:

    public class SampleRealmItem extends RealmObject implements IItem<SampleRealmItem, SampleRealmItem.ViewHolder> {
        // the identifier for this item
        @PrimaryKey
        protected long mIdentifier = -1;
    
        @Override
        public long getIdentifier() {
            return mIdentifier;
        }
    
        // the tag for this item
        @Ignore
        protected Object mTag;
    
        @Override
        public Object getTag() {
            return mTag;
        }
    
        // defines if this item is enabled
        @Ignore
        protected boolean mEnabled = true;
    
        @Override
        public boolean isEnabled() {
            return mEnabled;
        }
    
        // defines if the item is selected
        @Ignore
        protected boolean mSelected = false;
    
        @Override
        public SampleRealmItem withSetSelected(boolean selected) {
            this.mSelected = selected;
            return this;
        }
    
        @Override
        public boolean isSelected() {
            return mSelected;
        }
    
        // defines if this item is selectable
        @Ignore
        protected boolean mSelectable = true;
    
        @Override
        public SampleRealmItem withSelectable(boolean selectable) {
            this.mSelectable = selectable;
            return this;
        }
    
        @Override
        public boolean isSelectable() {
            return mSelectable;
        }
    
        @Override
        public int getType() {
            return R.id.some_id;
        }
    
        @Override
        public int getLayoutRes() {
            return R.layout.some_layout;
        }
    
        @Override
        public View generateView(Context ctx) {
            ViewHolder viewHolder = getViewHolder(LayoutInflater.from(ctx).inflate(getLayoutRes(), null, false));
            //as we already know the type of our ViewHolder cast it to our type
            bindView(viewHolder, Collections.EMPTY_LIST);
            //return the bound view
            return viewHolder.itemView;
        }
    
        @Override
        public View generateView(Context ctx, ViewGroup parent) {
            ViewHolder viewHolder = getViewHolder(LayoutInflater.from(ctx).inflate(getLayoutRes(), parent, false));
            //as we already know the type of our ViewHolder cast it to our type
            bindView(viewHolder, Collections.EMPTY_LIST);
            //return the bound and generatedView
            return viewHolder.itemView;
        }
    
        @Override
        public ViewHolder getViewHolder(ViewGroup parent) {
            return getViewHolder(LayoutInflater.from(parent.getContext()).inflate(getLayoutRes(), parent, false));
        }
    
        private ViewHolder getViewHolder(View v) {
            return new ViewHolder(v);
        }
    
        @Override
        public void bindView(ViewHolder holder, List<Object> payloads) {
            //set the selected state of this item. force this otherwise it may is missed when implementing an item
            holder.itemView.setSelected(isSelected());
            //set the tag of this item to this object (can be used when retrieving the view)
            holder.itemView.setTag(this);
    
            //handle your binding
        }
    
        @Override
        public void unbindView(ViewHolder holder) {
            holder.name.setText(null);
        }
    
        @Override
        public void attachToWindow(ViewHolder holder) {}
    
        @Override
        public void detachFromWindow(ViewHolder holder) {}
    
        @Override
        public boolean failedToRecycle(ViewHolder holder) {
            return false;
        }
    
        @Override
        public boolean equals(int id) {
            return id == mIdentifier;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            AbstractItem<?, ?> that = (AbstractItem<?, ?>) o;
            return mIdentifier == that.getIdentifier();
        }
    
        @Override
        public int hashCode() {
            return Long.valueOf(mIdentifier).hashCode();
        }
    
        protected static class ViewHolder extends RecyclerView.ViewHolder {
            public ViewHolder(View view) {
                super(view);
            }
        }
    }
    

    To simplify it, I have removed comments, and unnecessary setters. A full sample can be found in the FastAdapters sample source here: https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/items/RealmSampleUserItem.java

    In case you are interested, here you can find the default AbstractItem implementation: https://github.com/mikepenz/FastAdapter/blob/develop/library-core/src/main/java/com/mikepenz/fastadapter/items/AbstractItem.java