Implement RealmModel while extending AbstractItem

270 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
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