Implement multiple ViewHolder types in RecycleView adapter

后端 未结 9 1684
迷失自我
迷失自我 2020-12-13 16:34

It\'s maybe a discussion not a question.

Normal way to implement multiple types

As you know, if we want to implement multiple types in RecyclerView

9条回答
  •  天涯浪人
    2020-12-13 16:47

    Personally I like approach suggested by Yigit Boyar in this talk (fast forward to 31:07). Instead of returning a constant int from getItemViewType(), return the layout id directly, which is also an int and is guaranteed to be unique:

    
        @Override
        public int getItemViewType(int position) {
            switch (position) {
                case 0:
                    return R.layout.first;
                case 1:
                    return R.layout.second;
                default:
                    return R.layout.third;
            }
        }
    
    

    This will allow you to have following implementation in onCreateViewHolder():

    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View view = inflater.inflate(viewType, parent, false);
    
            MyViewHolder holder = null;
            switch (viewType) {
                case R.layout.first:
                    holder = new FirstViewHolder(view);
                    break;
                case R.layout.second:
                    holder = new SecondViewHolder(view);
                    break;
                case R.layout.third:
                    holder = new ThirdViewHolder(view);
                    break;
            }
            return holder;
        }
    
    

    Where MyViewHolder is an abstract class:

    
        public static abstract class MyViewHolder extends RecyclerView.ViewHolder {
    
            public MyViewHolder(View itemView) {
                super(itemView);
    
                // perform action specific to all viewholders, e.g.
                // ButterKnife.bind(this, itemView);
            }
    
            abstract void bind(Item item);
        }
    
    

    And FirstViewHolder is following:

    
        public static class FirstViewHolder extends MyViewHolder {
    
            @BindView
            TextView title;
    
            public FirstViewHolder(View itemView) {
                super(itemView);
            }
    
            @Override
            void bind(Item item) {
                title.setText(item.getTitle());
            }
        }
    
    

    This will make onBindViewHolder() to be one-liner:

    
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.bind(dataList.get(holder.getAdapterPosition()));
        }
    
    

    Thus, you'd have each ViewHolder separated, where bind(Item) would be responsible to perform actions specific to that ViewHolder only.

提交回复
热议问题