Skip to content Skip to sidebar Skip to footer

Listview To Recyclerview Migration For Customview

I see a need in my project to move from ListView to RecyclerView. I am facing some design issue. In my current ListView implementation I am using CustomView instead of inflating th

Solution 1:

It's pretty straight-forward to translate your ListView adapter to a RecyclerView.Adapter - I've written skeletons for both implementations below:

privatestaticclassMyRecyclerViewAdapterextendsRecyclerView.Adapter<CustomViewHolder> {

    @Overridepublic CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CustomViewview= createNewCustomView();
        returnnewCustomViewHolder(view);
    }

    private CustomView createNewCustomView() {
        // whatever you need to do to create - I would suggest create from XML rather new'ing up directlyreturnnull;
    }

    @OverridepublicvoidonBindViewHolder(CustomViewHolder holder, int position) {
        // bind the dataDataModeldataModel= getModelForPosition(position);
        holder.getCustomView().showView(dataModel, position);
    }

    private DataModel getModelForPosition(int position) {
        // TODO: however you did getModelForPosition(int)returnnull;
    }

    @OverridepublicintgetItemCount() {
        // TODO: same as getCount()return0;
    }

}

privatestaticclassCustomViewHolderextendsRecyclerView.ViewHolder {

    publicCustomViewHolder(CustomView itemView) {
        super(itemView);
    }

    CustomView getCustomView() {
        return ((CustomView) itemView);
    }

}

privatestaticclassMyListViewAdapterextendsBaseAdapter {

    @OverridepublicintgetCount() {
        // TODO: return correct list sizereturn0;
    }

    @Overridepublic DataModel getItem(int position) {
        // TODO: however you did getModelForPosition(int)returnnull;
    }

    @OverridepubliclonggetItemId(int position) {
        // however you doreturn0;
    }

    @Overridepublic View getView(int position, View containerRow, ViewGroup parent) {
        CustomViewcustomView= ((CustomView) containerRow);
        if (customView == null) {
            customView = createNewCustomView();
        }

        // could just use getItem(int) hereDataModeldataModel= getModelForPosition(position);

        // would it ever be null? if so, you'll have a blank list itemif (dataModel != null) {
            customView.showView(dataModel.getSingleDcyde(), position);
        }
        return customView;
    }

    private CustomView createNewCustomView() {
        // whatever you need to do to create - I would suggest create from XML rather new'ing up directlyreturnnull;
    }

    private DataModel getModelForPosition(int position) {
        return getItem(position);
    }

}

privatestaticclassDataModel {

    Object getSingleDcyde() {
        // whatever this isreturnnull;
    }

}

privatestaticclassCustomViewextendsView {

    publicCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    publicvoidshowView(Object singleDcyde, int position) {
        // bind
    }

}

What is the best way to keep design in sync with RecyclerView philosophy.

The philosophy behind RecyclerView is separation of concerns; the RecyclerView is responsible only for managing view recycling, the LayoutManager will decide how views are measured and positioned, the ViewHolder is an attempt to force the ViewHolder pattern (an approach to avoid multiple unnecessary calls to findViewById()), and the RecyclerView.Adapter is the glue that hooks your data up.

You're now forced to use the ViewHolder class. The idea is do all your findViewById() calls only once per inflated layout (whether or not this call is slow enough to bother doing is debated), e.g.:

privatestaticfinalclassCustomViewHolderextendsRecyclerView.ViewHolder {

    privatefinal TextView titleTextView;
    privatefinal ImageView avatarImageView;

    public CustomViewHolder newInstance(CustomView itemView) {
        returnnewCustomViewHolder(
                itemView,
                ((TextView) itemView.findViewById(R.id.title_text_view)),
                ((ImageView) itemView.findViewById(R.id.avatar_image_view))
        );
    }

    privateCustomViewHolder(CustomView itemView, TextView titleTextView, ImageView avatarImageView) {
        super(itemView);
        this.titleTextView = titleTextView;
        this.avatarImageView = avatarImageView;
    }

    publicvoidsetTitle(String title) {
        titleTextView.setText(title);
    }

    publicvoidsetAvatar(Drawable avatar) {
        avatarImageView.setImageDrawable(avatar);
    }

}

Actually, since you're using a custom View, it's very likely (I hope), that you're already avoiding multiple calls to findViewById(int) by using the HolderView pattern. In which case you can rebel against the tyranny of mandated ViewHolder usage by treating it as necessary evil:

privatestaticfinalclassCustomViewHolderextendsRecyclerView.ViewHolder {

    publicCustomViewHolder(CustomView itemView) {
        super(itemView);
    }

}

...
...

@OverridepublicvoidonBindViewHolder(CustomViewHolder holder, int position) {
    Foofoo= getFoo(position);
    ((CustomView) holder.itemView).myCustomBindMethod(foo);
}

Post a Comment for "Listview To Recyclerview Migration For Customview"