How implement multi view types for RecycleView?

坚强是说给别人听的谎言 提交于 2019-12-08 12:46:20

问题


Currently, I work on custom multi-view types for RecycleView. I found many solutions for this problem, but I will share my way.

The different is use enum for define ViewType.

See my answer for more detail. (Just want to share).


回答1:


UPDATE

I recommend read this article: Writing Better Adapter


Here is the way I custom multi-view types for RecyclewView.

I will show the code first, then explain bellow.

@SuppressWarnings("unchecked")
public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
    private final List<Wrapper<?>> items;

    public BaseAdapter() {
        this.items = new ArrayList<>();
    }

    @Override
    public int getItemViewType(int position) {
        return items.get(position).viewType;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return ViewType.values()[viewType].onCreateViewHolder(parent);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.onBind(items.get(position));
    }

    @Override
    public int getItemCount() {
        return items.size();
    }


    public void simulateAddItems() {
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.BOTTOM.viewTYpe(), new BottomData()));

        notifyDataSetChanged();
    }

    public enum ViewType {
        USER {
            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent) {
                return new UserViewHolder(itemView);
            }
        },
        BOTTOM {
            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent) {
                return new BottomViewHolder(itemView);
            }
        };

        public abstract ViewHolder onCreateViewHolder(ViewGroup parent);

        public int viewTYpe() {
            return ordinal();
        }
    }


    static class Wrapper<T> {
        final int viewType;
        final T data;

        public Wrapper(int viewType, T data) {
            this.viewType = viewType;
            this.data = data;
        }
    }

    public static class ViewHolder<T> extends RecyclerView.ViewHolder {
        private T item;

        public ViewHolder(View itemView) {
            super(itemView);
        }


        public void onBind(T item) {
        }
    }

    public static class UserViewHolder extends ViewHolder<User> {

        public UserViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void onBind(User item) {
            super.onBind(item);
        }
    }

    public static class BottomViewHolder extends ViewHolder<BottomData> {

        public BottomViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void onBind(BottomData item) {
            super.onBind(item);
        }
    }


    static class User {
        // user fields & method
    }

    static class BottomData {
        // bottom data fields & method
    }
}

You can see the adapter have something special:

  1. The data of Adapter is generic & extends from Wrapper class. The Wrapper class simply POJO class contain two fields viewType & item data. The viewType will be passing via getItemViewType(int position) and the item is data for each view holder.

  2. The generic ViewHolder with T is kind of data for the view holder. You can see two custom view holder UserViewHolder and BottomViewHolder extends from ViewHolder with this data. (So in onBind of each view holder will have exact data they want to use -> no need to cast. Because we already in cast).

  3. The enum ViewType contain all view type of adapter. Also, in view type, we have method ViewHolder onCreateViewHolder(ViewGroup parent) so we can easier make viewHolder from ViewType. I think it is easier for our eyes to see the Holder relative to the ViewType.

Also, we have method viewType() it simply return ordinal() of enum. As a reference in java docs that method may not use. But in this case, I think it is fair enough to use (because it is unique).

So in the method onCreateViewHolder of Adapter we can simple call: return ViewType.values()[viewType].onCreateViewHolder(parent);

and in onBindViewHolder we will call holder.onBind(items.get(position));.

Finally, I made simulateAddItems for demo how we add item to the adapter.

Here is some experiences while working with custom view type for RecycleView. I hope it useful & help other people.



来源:https://stackoverflow.com/questions/47245398/how-implement-multi-view-types-for-recycleview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!