Search code examples
androidandroid-roomtype-parameterbounded-typesfastadapter

Android Room: Is it possible to use bounded type parameters in an entity?


I am currently combining Mike Penz Fastadapter with Android Room. The expandable model class needs to be implemented like this:

public class MyClass<Parent extends IItem & IExpandable,
        SubItem extends IItem & ISubItem>
        extends AbstractExpandableItem<MyClass<Parent, SubItem>, MyClass.ViewHolder, SubItem> {

I want to use the model also as a room entity. The first problem was easy to solve - I created a custom version of AbstractExpandableItem where the fields would be annoteted with @Ignore tags to not brake the code generation. A simpler implementation of Fastadapter worked just fine this way.

However, Room seems to have a problem with bounded type parameters for entities, as it throws these compile errors in the DAO implementation:

  • Error:(40, 115) error: cannot find symbol class Parent
  • Error:(40, 123) error: cannot find symbol class SubItem

My DAO is:

    @Dao
public interface MyDAO {

    @Query("Select * from Table")
    LiveData<List<MyClass>> getAllStuff();

Unlike this guy, I could not solve my issues with an update - I put my Room gradle version on 1.1.1 and the error still happens.


Solution

  • The FastAdapter also offers the possibility to define a normal Model class, which can be a super simple POJO and a Item class.

    This way you can have all your data definition in the model, which will not require any parent classes or implementations, and the Item which will do the UI binding.

    A simple example can be found in the sample application of the FastAdapter.

    Instead of an ItemAdapter you will use a ModelAdapter, and then you provide the logic on how your model converts to a Item.

    This can be as simple as:

    ModelAdapter<IconModel, ModelIconItem> itemAdapter = new ModelAdapter<>(new IInterceptor<IconModel, ModelIconItem>() {
            @Override
            public ModelIconItem intercept(IconModel iconModel) {
                return new ModelIconItem(iconModel);
            }
    });
    

    For this simple sample the model looks like:

    public class IconModel {
        public IIcon icon;
    
        public IconModel(IIcon icon) {
            this.icon = icon;
        }
    }
    

    And the item looks like this:

    public class ModelIconItem extends ModelAbstractItem<com.mikepenz.fastadapter.app.model.IconModel, ModelIconItem, ModelIconItem.ViewHolder> {
        public ModelIconItem(com.mikepenz.fastadapter.app.model.IconModel icon) {
            super(icon);
        }
        @Override
        public int getType() {
            return R.id.fastadapter_model_icon_item_id;
        }
        @Override
        public int getLayoutRes() {
            return R.layout.icon_item;
        }
        @Override
        public void bindView(ViewHolder viewHolder, List<Object> payloads) {
            super.bindView(viewHolder, payloads);
    
            ... bind logic
        }
        @Override
        public ViewHolder getViewHolder(View v) {
            return new ViewHolder(v);
        }
        protected static class ViewHolder extends RecyclerView.ViewHolder {
            protected View view;
            @BindView(R.id.name)
            public TextView name;
            @BindView(R.id.icon)
            public IconicsImageView image;
    
            public ViewHolder(View view) {
                super(view);
                ButterKnife.bind(this, view);
                this.view = view;
            }
        }
    }
    

    The full sample code can be found here: https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/ModelItemActivity.java#L51