RecycleView的万能适配器

转载自http://www.cnblogs.com/liushilin/p/5720926.html

由于RecyclerView的Adapter必须继承自RecyclerView.Adapter,并且指定我们写的ViewHolder为泛型,为了达到万能的效果,我们把需要传入的Java Bean属性直接用一个泛型T指代。

下面这些值得你注意:

1)RecyclerView没有提供Item的点击事件,所以我们需要自己自定义,建议实现在Adapter中,因为adapter里面会用到ViewHolder,这样有助用我们写每一项的点击事件。

2)RecyclerView不仅支持全局刷新,而且支持局部刷新,所以我们建议把添加和删除的方法直接写在Adapter中。

3)我们为了达到万能的效果,所以我们把设置holder的方法作为一个抽象方法,方面我们通过viewId传值到相应的控件中,把整个Adapter变成一个抽象方法,这样在子类中就可以去通过强制实现的方式把我们的数据填充进去。

还是直接看源码吧。

  1 package com.example.nanchen.commonadaperrecyclerdemo;
  2 
  3 import android.content.Context;
  4 import android.support.v7.widget.RecyclerView;
  5 import android.view.LayoutInflater;
  6 import android.view.View;
  7 import android.view.ViewGroup;
  8 
  9 import java.util.List;
 10 
 11 /**
 12  * 万能的RecyclerView适配器
 13  * Created by 南尘 on 16-7-30.
 14  */
 15 public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseRecyclerHolder> {
 16 
 17     private Context context;//上下文
 18     private List<T> list;//数据源
 19     private LayoutInflater inflater;//布局器
 20     private int itemLayoutId;//布局id
 21     private boolean isScrolling;//是否在滚动
 22     private OnItemClickListener listener;//点击事件监听器
 23     private OnItemLongClickListener longClickListener;//长按监听器
 24     private RecyclerView recyclerView;
 25 
 26     //在RecyclerView提供数据的时候调用
 27     @Override
 28     public void onAttachedToRecyclerView(RecyclerView recyclerView) {
 29         super.onAttachedToRecyclerView(recyclerView);
 30         this.recyclerView = recyclerView;
 31     }
 32 
 33     @Override
 34     public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
 35         super.onDetachedFromRecyclerView(recyclerView);
 36         this.recyclerView = null;
 37     }
 38 
 39     /**
 40      * 定义一个点击事件接口回调
 41      */
 42     public interface OnItemClickListener {
 43         void onItemClick(RecyclerView parent, View view, int position);
 44     }
 45 
 46     public interface OnItemLongClickListener {
 47         boolean onItemLongClick(RecyclerView parent, View view, int position);
 48     }
 49 
 50     /**
 51      * 插入一项
 52      *
 53      * @param item
 54      * @param position
 55      */
 56     public void insert(T item, int position) {
 57         list.add(position, item);
 58         notifyItemInserted(position);
 59     }
 60 
 61     /**
 62      * 删除一项
 63      *
 64      * @param position 删除位置
 65      */
 66     public void delete(int position) {
 67         list.remove(position);
 68         notifyItemRemoved(position);
 69     }
 70 
 71     public BaseRecyclerAdapter(Context context, List<T> list, int itemLayoutId) {
 72         this.context = context;
 73         this.list = list;
 74         this.itemLayoutId = itemLayoutId;
 75         inflater = LayoutInflater.from(context);
 76 
 77         //        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
 78         //            @Override
 79         //            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
 80         //                super.onScrollStateChanged(recyclerView, newState);
 81         //                isScrolling = !(newState == RecyclerView.SCROLL_STATE_IDLE);
 82         //                if (!isScrolling) {
 83         //                    notifyDataSetChanged();
 84         //                }
 85         //            }
 86         //        });
 87     }
 88 
 89     @Override
 90     public BaseRecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 91         View view = inflater.inflate(itemLayoutId, parent, false);
 92         return BaseRecyclerHolder.getRecyclerHolder(context, view);
 93     }
 94 
 95     @Override
 96     public void onBindViewHolder(final BaseRecyclerHolder holder, int position) {
 97 
 98         if (listener != null){
 99             holder.itemView.setBackgroundResource(R.drawable.recycler_bg);//设置背景
100         }
101         holder.itemView.setOnClickListener(new View.OnClickListener() {
102             @Override
103             public void onClick(View view) {
104                 if (listener != null && view != null && recyclerView != null) {
105                     int position = recyclerView.getChildAdapterPosition(view);
106                     listener.onItemClick(recyclerView, view, position);
107                 }
108             }
109         });
110 
111 
112         holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
113             @Override
114             public boolean onLongClick(View view) {
115                 if (longClickListener != null && view != null && recyclerView != null) {
116                     int position = recyclerView.getChildAdapterPosition(view);
117                     longClickListener.onItemLongClick(recyclerView, view, position);
118                     return true;
119                 }
120                 return false;
121             }
122         });
123 
124         convert(holder, list.get(position), position, isScrolling);
125 
126     }
127 
128     @Override
129     public int getItemCount() {
130         return list == null ? 0 : list.size();
131     }
132 
133     public void setOnItemClickListener(OnItemClickListener listener) {
134         this.listener = listener;
135     }
136 
137     public void setOnItemLongClickListener(OnItemLongClickListener longClickListener) {
138         this.longClickListener = longClickListener;
139     }
140 
141     /**
142      * 填充RecyclerView适配器的方法,子类需要重写
143      *
144      * @param holder      ViewHolder
145      * @param item        子项
146      * @param position    位置
147      * @param isScrolling 是否在滑动
148      */
149     public abstract void convert(BaseRecyclerHolder holder, T item, int position, boolean isScrolling);
150 }

其他的代码就很简单了,java bean类Data和布局和昨天一样的,大家可以自己去随便怎么布局。

这里只上一个MainActivity的代码

 1 package com.example.nanchen.commonadaperrecyclerdemo;
 2 
 3 import android.os.Bundle;
 4 import android.support.v7.app.AppCompatActivity;
 5 import android.support.v7.widget.LinearLayoutManager;
 6 import android.support.v7.widget.RecyclerView;
 7 import android.view.View;
 8 import android.widget.EditText;
 9 import android.widget.Toast;
10 
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Locale;
14 
15 public class MainActivity extends AppCompatActivity {
16 
17     private List<Data> list;
18     private RecyclerView recyclerView;
19     private BaseRecyclerAdapter<Data> adapter;
20     private EditText text;
21 
22     @SuppressWarnings("unchecked")
23     @Override
24     protected void onCreate(Bundle savedInstanceState) {
25         super.onCreate(savedInstanceState);
26         setContentView(R.layout.activity_main);
27 
28         list = new ArrayList<>();
29 
30         initList();
31 
32         adapter = new BaseRecyclerAdapter<Data>(this,list,R.layout.list_item) {
33             @Override
34             public void convert(BaseRecyclerHolder holder, Data item, int position, boolean isScrolling) {
35                 holder.setText(R.id.item_text,item.getText());
36                 if (item.getImageUrl() != null){
37                     holder.setImageByUrl(R.id.item_image,item.getImageUrl());
38                 }else {
39                     holder.setImageResource(R.id.item_image,item.getImageId());
40                 }
41             }
42 
43         };
44 
45         adapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
46             @Override
47             public void onItemClick(RecyclerView parent, final View view, int position) {
48                 Toast.makeText(MainActivity.this, String.format(Locale.CHINA,"你点击了第%d项,长按会删除!",position),Toast.LENGTH_SHORT).show();
49             }
50         });
51 
52         adapter.setOnItemLongClickListener(new BaseRecyclerAdapter.OnItemLongClickListener() {
53             @Override
54             public boolean onItemLongClick(RecyclerView parent, View view, int position) {
55                 adapter.delete(position);
56                 return true;
57             }
58         });
59 
60         text = (EditText) findViewById(R.id.main_text);
61         recyclerView = (RecyclerView) findViewById(R.id.main_recycler);
62         recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
63         recyclerView.setAdapter(adapter);
64 
65 
66 
67     }
68 
69     public void initList(){
70         for (int i = 0; i < 5; i++) {
71             list.add(new Data("本地 "+i,R.mipmap.ic_launcher));
72         }
73         for (int i = 0; i < 5; i++) {
74             list.add(new Data("网络 "+i,"http://pic.cnblogs.com/face/845964/20160301162812.png"));
75         }
76     }
77 
78     public void btnClick(View view) {
79         String string = text.getText().toString().trim();
80         Data data = new Data(string,R.mipmap.ic_launcher);
81 //        list.add(list.size()/2,data);
82         adapter.insert(data,list.size()/2);
83 
84         Toast.makeText(MainActivity.this,list.size()+"",Toast.LENGTH_SHORT).show();
85     }
86 }
原文地址:https://www.cnblogs.com/cct1314520/p/6545150.html