Implement RealmModel while extending AbstractItem

275 Views Asked by At

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.

1

There are 1 best solutions below

3
mikepenz On BEST ANSWER

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