通用适配器

CommonAdapter:listview、gridview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public abstract class CommonAdapter<T> extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected final int mItemLayoutId;

public CommonAdapter(Context context, List<T> mDatas, int mItemLayoutId) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = mDatas;
this.mItemLayoutId = mItemLayoutId;
}

@Override
public int getCount() {
return mDatas.size();
}

@Override
public T getItem(int position) {
return mDatas.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder = getViewHolder(position, convertView, parent);
convert(viewHolder, getItem(position));
return viewHolder.getConvertView();
}

protected abstract void convert(ViewHolder viewHolder, T item);

private ViewHolder getViewHolder(int position, View convertView, ViewGroup parent) {
return ViewHolder.get(mContext, convertView, parent, mItemLayoutId, position);
}
}
public class ViewHolder {
private SparseArray<View> mViews;
private View mConvertView;
private int mPosition;
private Context mContext;

private ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
this.mViews = new SparseArray<View>();
mPosition = position;
mContext = context;
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
//setTag
mConvertView.setTag(this);
}

/**
* 拿到一个ViewHolder对象
*
* @param context
* @param convertView
* @param parent
* @param layoutId
* @param postion
* @return
*/
public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int postion) {
if (convertView == null) {
return new ViewHolder(context, parent, layoutId, postion);
}
return (ViewHolder) convertView.getTag();
}

/**
* 通过控件的Id获取对应的控件,如果没有则加入views
*
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}

public View getConvertView() {
return mConvertView;
}

/**
* 为TextView 设置字符串
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text) {
TextView view = getView(viewId);
view.setText(text);
view.setTextColor(Color.BLACK);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param drawableId
* @return
*/
public ViewHolder setImageResource(int viewId, int drawableId) {
ImageView view = getView(viewId);
view.setImageResource(drawableId);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param bm
* @return
*/
public ViewHolder setImageBitmap(int viewId, Bitmap bm) {
ImageView view = getView(viewId);
view.setImageBitmap(bm);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param url
* @return
*/
public ViewHolder setImageByUrl(int viewId, String url) {
// ImageDownLoad.getDownLoadSmallImg(url, (ImageView) getView(viewId));
PicassoUtils.getinstance().loadImageByPath(mContext, url, (ImageView) getView(viewId), PicassoUtils.PICASSO_BITMAP_SHOW_NORMAL_TYPE, -1);
return this;
}

public int getPosition() {
return mPosition;
}
}

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private CommonAdapter<ApplyBean.DataBean> myApplyAdapter;
((MyApplyFragment) t).lv.setAdapter(((MyApplyFragment) t).myApplyAdapter = new CommonAdapter<ApplyBean.DataBean>(
t.getActivity().getApplicationContext(), ((MyApplyFragment) t).myApplys, R.layout.item_fragment_myapply
) {
@Override
protected void convert(ViewHolder viewHolder, ApplyBean.DataBean item) {
TextView stateTv = viewHolder.getView(R.id.item_fragment_myapply_state_tv);
if (item.getStatus() == 3) {//0:处理完成 1:正在处理 3:驳回
stateTv.setBackgroundColor(t.getActivity().getResources().getColor(R.color.red));
} else if (item.getStatus() == 0) {
stateTv.setBackgroundColor(t.getActivity().getResources().getColor(R.color.green));
} else {
stateTv.setBackgroundColor(t.getActivity().getResources().getColor(R.color.gray));
}
TextView nameTv = viewHolder.getView(R.id.item_fragment_myapply_name_tv);
nameTv.setText(item.getName());
nameTv.setTextColor(t.getActivity().getResources().getColor(R.color.gray));

TextView dateTv = viewHolder.getView(R.id.item_fragment_myapply_date_tv);
dateTv.setTextColor(t.getActivity().getResources().getColor(R.color.gray));
dateTv.setText(item.getAdd_time());
}
});

CommonChoseAbleAdapter:listview、gridview带选中tv的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import android.widget.BaseAdapter;

/**通用adapter,点击改变背景色
*/
public abstract class CommonChoseAbleAdapter<T> extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected final int mItemLayoutId;
protected final int mItemRootLayoutId;

public CommonChoseAbleAdapter(Context context, List<T> mDatas, int mItemLayoutId, int mItemRootLayoutId) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mDatas = mDatas;
this.mItemLayoutId = mItemLayoutId;
this.mItemRootLayoutId = mItemRootLayoutId;
}

@Override
public int getCount() {
return mDatas.size();
}

@Override
public T getItem(int position) {
return mDatas.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder = getViewHolder(position, convertView, parent);
convert(viewHolder, getItem(position));

TextView tv = viewHolder.getView(mItemRootLayoutId);
if (position == selectItem) {
tv.setTextColor(Color.BLACK);
} else {
tv.setTextColor(Color.GRAY);
}

return viewHolder.getConvertView();
}

private int selectItem = -1;

public int getSelectItem() {
return selectItem;
}

public void setSelectItem(int selectItem) {
this.selectItem = selectItem;
}

protected abstract void convert(ViewHolder viewHolder, T item);

private ViewHolder getViewHolder(int position, View convertView, ViewGroup parent) {
return ViewHolder.get(mContext, convertView, parent, mItemLayoutId, position);
}
}
public class ViewHolder {
private SparseArray<View> mViews;
private View mConvertView;
private int mPosition;
private Context mContext;

private ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
this.mViews = new SparseArray<View>();
mPosition = position;
mContext = context;
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
//setTag
mConvertView.setTag(this);
}

/**
* 拿到一个ViewHolder对象
*
* @param context
* @param convertView
* @param parent
* @param layoutId
* @param postion
* @return
*/
public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int postion) {
if (convertView == null) {
return new ViewHolder(context, parent, layoutId, postion);
}
return (ViewHolder) convertView.getTag();
}

/**
* 通过控件的Id获取对应的控件,如果没有则加入views
*
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}

public View getConvertView() {
return mConvertView;
}

/**
* 为TextView 设置字符串
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text) {
TextView view = getView(viewId);
view.setText(text);
view.setTextColor(Color.BLACK);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param drawableId
* @return
*/
public ViewHolder setImageResource(int viewId, int drawableId) {
ImageView view = getView(viewId);
view.setImageResource(drawableId);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param bm
* @return
*/
public ViewHolder setImageBitmap(int viewId, Bitmap bm) {
ImageView view = getView(viewId);
view.setImageBitmap(bm);
return this;
}

/**
* 为ImageView 设置图片
*
* @param viewId
* @param url
* @return
*/
public ViewHolder setImageByUrl(int viewId, String url) {
// ImageDownLoad.getDownLoadSmallImg(url, (ImageView) getView(viewId));
PicassoUtils.getinstance().loadImageByPath(mContext, url, (ImageView) getView(viewId), PicassoUtils.PICASSO_BITMAP_SHOW_NORMAL_TYPE, -1);
return this;
}

public int getPosition() {
return mPosition;
}
}

CommonAdapter:RecyclerView

CommonRvAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import android.content.Context;
import android.view.LayoutInflater;

import com.xm597.common.utils.adapter.rvadapter.base.ItemViewDelegate;
import com.xm597.common.utils.adapter.rvadapter.base.ViewHolder;

import java.util.List;

public abstract class CommonRvAdapter<T> extends MultiItemTypeAdapter<T> {
protected Context mContext;
protected int mLayoutId;
protected List<T> mDatas;
protected LayoutInflater mInflater;

public CommonRvAdapter(final Context context, final int layoutId, List<T> datas) {
super(context, datas);
mContext = context;
mInflater = LayoutInflater.from(context);
mLayoutId = layoutId;
mDatas = datas;

addItemViewDelegate(new ItemViewDelegate<T>() {
@Override
public int getItemViewLayoutId() {
return layoutId;
}

@Override
public boolean isForViewType(T item, int position) {
return true;
}

@Override
public void convert(ViewHolder holder, T t, int position) {
CommonRvAdapter.this.convert(holder, t, position);
}
});
}

protected abstract void convert(ViewHolder holder, T t, int position);
}

MultiItemTypeAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;


import androidx.recyclerview.widget.RecyclerView;

import com.xm597.common.utils.adapter.rvadapter.base.ItemViewDelegate;
import com.xm597.common.utils.adapter.rvadapter.base.ItemViewDelegateManager;
import com.xm597.common.utils.adapter.rvadapter.base.ViewHolder;

import java.util.List;

public class MultiItemTypeAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
protected Context mContext;
protected List<T> mDatas;

protected ItemViewDelegateManager mItemViewDelegateManager;
protected OnItemClickListener mOnItemClickListener;


public MultiItemTypeAdapter(Context context, List<T> datas) {
mContext = context;
mDatas = datas;
mItemViewDelegateManager = new ItemViewDelegateManager();
}

@Override
public int getItemViewType(int position) {
if (!useItemViewDelegateManager()) {
return super.getItemViewType(position);
}
return mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
}


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ItemViewDelegate itemViewDelegate = mItemViewDelegateManager.getItemViewDelegate(viewType);
int layoutId = itemViewDelegate.getItemViewLayoutId();
ViewHolder holder = ViewHolder.createViewHolder(mContext, parent, layoutId);
onViewHolderCreated(holder, holder.getConvertView());
//setListener(parent, holder, viewType);
return holder;
}

public void onViewHolderCreated(ViewHolder holder, View itemView) {

}

public void convert(ViewHolder holder, T t) {
mItemViewDelegateManager.convert(holder, t, holder.getAdapterPosition());
}

protected boolean isEnabled(int viewType) {
return true;
}


protected void setListener(final ViewGroup parent, final ViewHolder viewHolder, int viewType) {
if (!isEnabled(viewType)) {
return;
}
viewHolder.getConvertView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
int position = viewHolder.getAdapterPosition();
mOnItemClickListener.onItemClick(v, viewHolder, position);
}
}
});

viewHolder.getConvertView().setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemClickListener != null) {
int position = viewHolder.getAdapterPosition();
return mOnItemClickListener.onItemLongClick(v, viewHolder, position);
}
return false;
}
});
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
convert(holder, mDatas.get(position));
holder.getConvertView().setOnClickListener(v -> {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(v, holder, position);
}
});

holder.getConvertView().setOnLongClickListener(v -> {
if (mOnItemClickListener != null) {
return mOnItemClickListener.onItemLongClick(v, holder, position);
}
return false;
});
}

@Override
public int getItemCount() {
int itemCount = mDatas.size();
return itemCount;
}


public List<T> getDatas() {
return mDatas;
}

public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(itemViewDelegate);
return this;
}

public MultiItemTypeAdapter addItemViewDelegate(int viewType, ItemViewDelegate<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(viewType, itemViewDelegate);
return this;
}

protected boolean useItemViewDelegateManager() {
return mItemViewDelegateManager.getItemViewDelegateCount() > 0;
}

public interface OnItemClickListener {
void onItemClick(View view, RecyclerView.ViewHolder holder, int position);

boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position);
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
}

base文件夹下

ItemViewDelegate

1
2
3
4
5
6
7
public interface ItemViewDelegate<T> {
int getItemViewLayoutId();

boolean isForViewType(T item, int position);

void convert(ViewHolder holder, T t, int position);
}

ItemViewDelegateManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import androidx.collection.SparseArrayCompat;

public class ItemViewDelegateManager<T> {
SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();

public int getItemViewDelegateCount() {
return delegates.size();
}

public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate) {
int viewType = delegates.size();
if (delegate != null) {
delegates.put(viewType, delegate);
viewType++;
}
return this;
}

public ItemViewDelegateManager<T> addDelegate(int viewType, ItemViewDelegate<T> delegate) {
if (delegates.get(viewType) != null) {
throw new IllegalArgumentException(
"An ItemViewDelegate is already registered for the viewType = "
+ viewType
+ ". Already registered ItemViewDelegate is "
+ delegates.get(viewType));
}
delegates.put(viewType, delegate);
return this;
}

public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate) {
if (delegate == null) {
throw new NullPointerException("ItemViewDelegate is null");
}
int indexToRemove = delegates.indexOfValue(delegate);

if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove);
}
return this;
}

public ItemViewDelegateManager<T> removeDelegate(int itemType) {
int indexToRemove = delegates.indexOfKey(itemType);

if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove);
}
return this;
}

public int getItemViewType(T item, int position) {
int delegatesCount = delegates.size();
for (int i = delegatesCount - 1; i >= 0; i--) {
ItemViewDelegate<T> delegate = delegates.valueAt(i);
if (delegate.isForViewType(item, position)) {
return delegates.keyAt(i);
}
}
throw new IllegalArgumentException(
"No ItemViewDelegate added that matches position=" + position + " in data source");
}

public void convert(ViewHolder holder, T item, int position) {
int delegatesCount = delegates.size();
for (int i = 0; i < delegatesCount; i++) {
ItemViewDelegate<T> delegate = delegates.valueAt(i);

if (delegate.isForViewType(item, position)) {
delegate.convert(holder, item, position);
return;
}
}
throw new IllegalArgumentException(
"No ItemViewDelegateManager added that matches position=" + position + " in data source");
}


public ItemViewDelegate getItemViewDelegate(int viewType) {
return delegates.get(viewType);
}

public int getItemViewLayoutId(int viewType) {
return getItemViewDelegate(viewType).getItemViewLayoutId();
}

public int getItemViewType(ItemViewDelegate itemViewDelegate) {
return delegates.indexOfValue(itemViewDelegate);
}
}

ViewHolder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.util.Linkify;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

public class ViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> mViews;
private View mConvertView;
private Context mContext;

public ViewHolder(Context context, View itemView) {
super(itemView);
mContext = context;
mConvertView = itemView;
mViews = new SparseArray<View>();
}


public static ViewHolder createViewHolder(Context context, View itemView) {
ViewHolder holder = new ViewHolder(context, itemView);
return holder;
}

public static ViewHolder createViewHolder(Context context,
ViewGroup parent, int layoutId) {
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
ViewHolder holder = new ViewHolder(context, itemView);
return holder;
}

/**
* 通过viewId获取控件
*
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}

public View getConvertView() {
return mConvertView;
}


/****以下为辅助方法*****/

/**
* 设置TextView的值
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text) {
TextView tv = getView(viewId);
tv.setText(text);
return this;
}

public ViewHolder setImageResource(int viewId, int resId) {
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}

public ViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}

public ViewHolder setImageDrawable(int viewId, Drawable drawable) {
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}

public ViewHolder setBackgroundColor(int viewId, int color) {
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}

public ViewHolder setBackgroundRes(int viewId, int backgroundRes) {
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}

public ViewHolder setTextColor(int viewId, int textColor) {
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}

public ViewHolder setTextColorRes(int viewId, int textColorRes) {
TextView view = getView(viewId);
view.setTextColor(mContext.getResources().getColor(textColorRes));
return this;
}

@SuppressLint("NewApi")
public ViewHolder setAlpha(int viewId, float value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getView(viewId).setAlpha(value);
} else {
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0);
alpha.setFillAfter(true);
getView(viewId).startAnimation(alpha);
}
return this;
}

public ViewHolder setVisible(int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}

public ViewHolder linkify(int viewId) {
TextView view = getView(viewId);
Linkify.addLinks(view, Linkify.ALL);
return this;
}

public ViewHolder setTypeface(Typeface typeface, int... viewIds) {
for (int viewId : viewIds) {
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
return this;
}

public ViewHolder setProgress(int viewId, int progress) {
ProgressBar view = getView(viewId);
view.setProgress(progress);
return this;
}

public ViewHolder setProgress(int viewId, int progress, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}

public ViewHolder setMax(int viewId, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}

public ViewHolder setRating(int viewId, float rating) {
RatingBar view = getView(viewId);
view.setRating(rating);
return this;
}

public ViewHolder setRating(int viewId, float rating, int max) {
RatingBar view = getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}

public ViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return this;
}

public ViewHolder setTag(int viewId, int key, Object tag) {
View view = getView(viewId);
view.setTag(key, tag);
return this;
}

public ViewHolder setChecked(int viewId, boolean checked) {
Checkable view = (Checkable) getView(viewId);
view.setChecked(checked);
return this;
}

/**
* 关于事件的
*/
public ViewHolder setOnClickListener(int viewId,
View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}

public ViewHolder setOnTouchListener(int viewId,
View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}

public ViewHolder setOnLongClickListener(int viewId,
View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
}

utils文件夹下

WrapperUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

public class WrapperUtils {
public interface SpanSizeCallback {
int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position);
}

public static void onAttachedToRecyclerView(RecyclerView.Adapter innerAdapter, RecyclerView recyclerView, final SpanSizeCallback callback) {
innerAdapter.onAttachedToRecyclerView(recyclerView);

RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();

gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return callback.getSpanSize(gridLayoutManager, spanSizeLookup, position);
}
});
gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
}
}

public static void setFullSpan(RecyclerView.ViewHolder holder) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();

if (lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
}
}

wrapper文件夹下

EmptyWrapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.xm597.common.utils.adapter.rvadapter.base.ViewHolder;
import com.xm597.common.utils.adapter.rvadapter.utils.WrapperUtils;

public class EmptyWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int ITEM_TYPE_EMPTY = Integer.MAX_VALUE - 1;

private RecyclerView.Adapter mInnerAdapter;
private View mEmptyView;
private int mEmptyLayoutId;


public EmptyWrapper(RecyclerView.Adapter adapter) {
mInnerAdapter = adapter;
}

private boolean isEmpty() {
return (mEmptyView != null || mEmptyLayoutId != 0) && mInnerAdapter.getItemCount() == 0;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (isEmpty()) {
ViewHolder holder;
if (mEmptyView != null) {
holder = ViewHolder.createViewHolder(parent.getContext(), mEmptyView);
} else {
holder = ViewHolder.createViewHolder(parent.getContext(), parent, mEmptyLayoutId);
}
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() {
@Override
public int getSpanSize(GridLayoutManager gridLayoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) {
if (isEmpty()) {
return gridLayoutManager.getSpanCount();
}
if (oldLookup != null) {
return oldLookup.getSpanSize(position);
}
return 1;
}
});


}

@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
mInnerAdapter.onViewAttachedToWindow(holder);
if (isEmpty()) {
WrapperUtils.setFullSpan(holder);
}
}


@Override
public int getItemViewType(int position) {
if (isEmpty()) {
return ITEM_TYPE_EMPTY;
}
return mInnerAdapter.getItemViewType(position);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (isEmpty()) {
return;
}
mInnerAdapter.onBindViewHolder(holder, position);
}

@Override
public int getItemCount() {
if (isEmpty()) {
return 1;
}
return mInnerAdapter.getItemCount();
}


public void setEmptyView(View emptyView) {
mEmptyView = emptyView;
}

public void setEmptyView(int layoutId) {
mEmptyLayoutId = layoutId;
}
}

HeaderAndFooterWrapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import android.view.View;
import android.view.ViewGroup;

import androidx.collection.SparseArrayCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.xm597.common.utils.adapter.rvadapter.base.ViewHolder;
import com.xm597.common.utils.adapter.rvadapter.utils.WrapperUtils;


public class HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int BASE_ITEM_TYPE_HEADER = 100000;
private static final int BASE_ITEM_TYPE_FOOTER = 200000;

private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();

private RecyclerView.Adapter mInnerAdapter;

public HeaderAndFooterWrapper(RecyclerView.Adapter adapter) {
mInnerAdapter = adapter;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mHeaderViews.get(viewType) != null) {
ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));
return holder;

} else if (mFootViews.get(viewType) != null) {
ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}

@Override
public int getItemViewType(int position) {
if (isHeaderViewPos(position)) {
return mHeaderViews.keyAt(position);
} else if (isFooterViewPos(position)) {
return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
}
return mInnerAdapter.getItemViewType(position - getHeadersCount());
}

private int getRealItemCount() {
return mInnerAdapter.getItemCount();
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (isHeaderViewPos(position)) {
return;
}
if (isFooterViewPos(position)) {
return;
}
mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());
}

@Override
public int getItemCount() {
return getHeadersCount() + getFootersCount() + getRealItemCount();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() {
@Override
public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) {
int viewType = getItemViewType(position);
if (mHeaderViews.get(viewType) != null) {
return layoutManager.getSpanCount();
} else if (mFootViews.get(viewType) != null) {
return layoutManager.getSpanCount();
}
if (oldLookup != null) {
return oldLookup.getSpanSize(position);
}
return 1;
}
});
}

@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
mInnerAdapter.onViewAttachedToWindow(holder);
int position = holder.getLayoutPosition();
if (isHeaderViewPos(position) || isFooterViewPos(position)) {
WrapperUtils.setFullSpan(holder);
}
}

private boolean isHeaderViewPos(int position) {
return position < getHeadersCount();
}

private boolean isFooterViewPos(int position) {
return position >= getHeadersCount() + getRealItemCount();
}


public void addHeaderView(View view) {
mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
}

public void addFootView(View view) {
mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
}

public int getHeadersCount() {
return mHeaderViews.size();
}

public int getFootersCount() {
return mFootViews.size();
}
}

LoadMoreWrapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import com.xm597.common.utils.adapter.rvadapter.base.ViewHolder;
import com.xm597.common.utils.adapter.rvadapter.utils.WrapperUtils;

public class LoadMoreWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int ITEM_TYPE_LOAD_MORE = Integer.MAX_VALUE - 2;

private RecyclerView.Adapter mInnerAdapter;
private View mLoadMoreView;
private int mLoadMoreLayoutId;

public LoadMoreWrapper(RecyclerView.Adapter adapter) {
mInnerAdapter = adapter;
}

private boolean hasLoadMore() {
return mLoadMoreView != null || mLoadMoreLayoutId != 0;
}


private boolean isShowLoadMore(int position) {
return hasLoadMore() && (position >= mInnerAdapter.getItemCount());
}

@Override
public int getItemViewType(int position) {
if (isShowLoadMore(position)) {
return ITEM_TYPE_LOAD_MORE;
}
return mInnerAdapter.getItemViewType(position);
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_TYPE_LOAD_MORE) {
ViewHolder holder;
if (mLoadMoreView != null) {
holder = ViewHolder.createViewHolder(parent.getContext(), mLoadMoreView);
} else {
holder = ViewHolder.createViewHolder(parent.getContext(), parent, mLoadMoreLayoutId);
}
return holder;
}
return mInnerAdapter.onCreateViewHolder(parent, viewType);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (isShowLoadMore(position)) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMoreRequested();
}
return;
}
mInnerAdapter.onBindViewHolder(holder, position);
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() {
@Override
public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) {
if (isShowLoadMore(position)) {
return layoutManager.getSpanCount();
}
if (oldLookup != null) {
return oldLookup.getSpanSize(position);
}
return 1;
}
});
}


@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
mInnerAdapter.onViewAttachedToWindow(holder);

if (isShowLoadMore(holder.getLayoutPosition())) {
setFullSpan(holder);
}
}

private void setFullSpan(RecyclerView.ViewHolder holder) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();

if (lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;

p.setFullSpan(true);
}
}

@Override
public int getItemCount() {
return mInnerAdapter.getItemCount() + (hasLoadMore() ? 1 : 0);
}


public interface OnLoadMoreListener {
void onLoadMoreRequested();
}

private OnLoadMoreListener mOnLoadMoreListener;

public LoadMoreWrapper setOnLoadMoreListener(OnLoadMoreListener loadMoreListener) {
if (loadMoreListener != null) {
mOnLoadMoreListener = loadMoreListener;
}
return this;
}

public LoadMoreWrapper setLoadMoreView(View loadMoreView) {
mLoadMoreView = loadMoreView;
return this;
}

public LoadMoreWrapper setLoadMoreView(int layoutId) {
mLoadMoreLayoutId = layoutId;
return this;
}
}

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.zhy.adapter.recyclerview.CommonAdapter;
import com.zhy.adapter.recyclerview.base.ViewHolder;
import com.zhy.adapter.recyclerview.wrapper.EmptyWrapper;
import com.zhy.adapter.recyclerview.wrapper.HeaderAndFooterWrapper;
import com.zhy.adapter.recyclerview.wrapper.LoadMoreWrapper;

import java.util.ArrayList;
import java.util.List;

public class RecyclerViewActivity extends AppCompatActivity {

private RecyclerView mRecyclerView;
private List<String> mDatas = new ArrayList<>();
private CommonAdapter<String> mAdapter;
private HeaderAndFooterWrapper mHeaderAndFooterWrapper;
private EmptyWrapper mEmptyWrapper;
private LoadMoreWrapper mLoadMoreWrapper;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);

initDatas();

mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
// mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
// mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

mAdapter = new CommonAdapter<String>(this, R.layout.item_list, mDatas) {
@Override
protected void convert(ViewHolder holder, String s, int position) {
holder.setText(R.id.id_item_list_title, s + " : " + holder.getAdapterPosition() + " , " + holder.getLayoutPosition());
}
};

initHeaderAndFooter();

// initEmptyView();

mLoadMoreWrapper = new LoadMoreWrapper(mHeaderAndFooterWrapper);
mLoadMoreWrapper.setLoadMoreView(R.layout.default_loading);
mLoadMoreWrapper.setOnLoadMoreListener(new LoadMoreWrapper.OnLoadMoreListener() {
@Override
public void onLoadMoreRequested() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
mDatas.add("Add:" + i);
}
mLoadMoreWrapper.notifyDataSetChanged();

}
}, 3000);
}
});

mRecyclerView.setAdapter(mLoadMoreWrapper);
mAdapter.setOnItemClickListener(new CommonAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
Toast.makeText(RecyclerViewActivity.this, "pos = " + position, Toast.LENGTH_SHORT).show();
mAdapter.notifyItemRemoved(position);
}

@Override
public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {
return false;
}
});
}

private void initEmptyView() {
mEmptyWrapper = new EmptyWrapper(mAdapter);
mEmptyWrapper.setEmptyView(LayoutInflater.from(this).inflate(R.layout.empty_view, mRecyclerView, false));
}

private void initHeaderAndFooter() {
mHeaderAndFooterWrapper = new HeaderAndFooterWrapper(mAdapter);

TextView t1 = new TextView(this);
t1.setText("Header 1");
TextView t2 = new TextView(this);
t2.setText("Header 2");
mHeaderAndFooterWrapper.addHeaderView(t1);
mHeaderAndFooterWrapper.addHeaderView(t2);
}

private void initDatas() {
for (int i = 'A'; i <= 'z'; i++) {
mDatas.add((char) i + "");
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_recycler_view, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
switch (id) {
case R.id.action_linear:
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
break;
case R.id.action_grid:
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
break;
case R.id.action_staggered:
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
break;
}
mRecyclerView.setAdapter(mLoadMoreWrapper);
return super.onOptionsItemSelected(item);
}
}

CommonAdapter:ListView、GridView

与CommonAdapter:RecyclerView是同一个作者

CommonAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import android.content.Context;
import android.view.View;

import com.zhy.adapter.abslistview.base.ItemViewDelegate;

import java.util.List;

public abstract class CommonAdapter<T> extends MultiItemTypeAdapter<T> {

public CommonAdapter(Context context, final int layoutId, List<T> datas) {
super(context, datas);

addItemViewDelegate(new ItemViewDelegate<T>() {
@Override
public int getItemViewLayoutId() {
return layoutId;
}

@Override
public boolean isForViewType(T item, int position) {
return true;
}

@Override
public void convert(ViewHolder holder, T t, int position) {
CommonAdapter.this.convert(holder, t, position);
}
});
}

protected abstract void convert(ViewHolder viewHolder, T item, int position);
}

MultiItemTypeAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;

public class MultiItemTypeAdapter<T> extends BaseAdapter {
protected Context mContext;
protected List<T> mDatas;

private ItemViewDelegateManager mItemViewDelegateManager;

public MultiItemTypeAdapter(Context context, List<T> datas) {
this.mContext = context;
this.mDatas = datas;
mItemViewDelegateManager = new ItemViewDelegateManager();
}

public MultiItemTypeAdapter addItemViewDelegate(ItemViewDelegate<T> itemViewDelegate) {
mItemViewDelegateManager.addDelegate(itemViewDelegate);
return this;
}

private boolean useItemViewDelegateManager() {
return mItemViewDelegateManager.getItemViewDelegateCount() > 0;
}

@Override
public int getViewTypeCount() {
if (useItemViewDelegateManager())
return mItemViewDelegateManager.getItemViewDelegateCount();
return super.getViewTypeCount();
}

@Override
public int getItemViewType(int position) {
if (useItemViewDelegateManager()) {
int viewType = mItemViewDelegateManager.getItemViewType(mDatas.get(position), position);
return viewType;
}
return super.getItemViewType(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewDelegate itemViewDelegate =
mItemViewDelegateManager.getItemViewDelegate(mDatas.get(position), position);
int layoutId = itemViewDelegate.getItemViewLayoutId();
ViewHolder viewHolder = null;
if (convertView == null) {
View itemView = LayoutInflater.from(mContext).inflate(layoutId, parent,
false);
viewHolder = new ViewHolder(mContext, itemView, parent, position);
viewHolder.mLayoutId = layoutId;
onViewHolderCreated(viewHolder, viewHolder.getConvertView());
} else {
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.mPosition = position;
}


convert(viewHolder, getItem(position), position);
return viewHolder.getConvertView();
}

protected void convert(ViewHolder viewHolder, T item, int position) {
mItemViewDelegateManager.convert(viewHolder, item, position);
}

public void onViewHolderCreated(ViewHolder holder, View itemView) {
}

@Override
public int getCount() {
return mDatas.size();
}

@Override
public T getItem(int position) {
return mDatas.get(position);
}

@Override
public long getItemId(int position) {
return position;
}
}

ViewHolder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.util.Linkify;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RatingBar;
import android.widget.TextView;

public class ViewHolder {
private SparseArray<View> mViews;
protected int mPosition;
private View mConvertView;
private Context mContext;
protected int mLayoutId;

public ViewHolder(Context context, View itemView, ViewGroup parent, int position) {
mContext = context;
mConvertView = itemView;
mPosition = position;
mViews = new SparseArray<View>();
mConvertView.setTag(this);
}


public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int layoutId, int position) {
if (convertView == null) {
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
ViewHolder holder = new ViewHolder(context, itemView, parent, position);
holder.mLayoutId = layoutId;
return holder;
} else {
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition = position;
return holder;
}
}


/**
* 通过viewId获取控件
*
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}

public View getConvertView() {
return mConvertView;
}

public int getLayoutId() {
return mLayoutId;
}

public void updatePosition(int position) {
mPosition = position;
}

public int getItemPosition() {
return mPosition;
}


/****以下为辅助方法*****/

/**
* 设置TextView的值
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text) {
TextView tv = getView(viewId);
tv.setText(text);
return this;
}

public ViewHolder setImageResource(int viewId, int resId) {
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}

public ViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}

public ViewHolder setImageDrawable(int viewId, Drawable drawable) {
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}

public ViewHolder setBackgroundColor(int viewId, int color) {
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}

public ViewHolder setBackgroundRes(int viewId, int backgroundRes) {
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}

public ViewHolder setTextColor(int viewId, int textColor) {
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}

public ViewHolder setTextColorRes(int viewId, int textColorRes) {
TextView view = getView(viewId);
view.setTextColor(mContext.getResources().getColor(textColorRes));
return this;
}

@SuppressLint("NewApi")
public ViewHolder setAlpha(int viewId, float value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getView(viewId).setAlpha(value);
} else {
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0);
alpha.setFillAfter(true);
getView(viewId).startAnimation(alpha);
}
return this;
}

public ViewHolder setVisible(int viewId, boolean visible) {
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}

public ViewHolder linkify(int viewId) {
TextView view = getView(viewId);
Linkify.addLinks(view, Linkify.ALL);
return this;
}

public ViewHolder setTypeface(Typeface typeface, int... viewIds) {
for (int viewId : viewIds) {
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
return this;
}

public ViewHolder setProgress(int viewId, int progress) {
ProgressBar view = getView(viewId);
view.setProgress(progress);
return this;
}

public ViewHolder setProgress(int viewId, int progress, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}

public ViewHolder setMax(int viewId, int max) {
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}

public ViewHolder setRating(int viewId, float rating) {
RatingBar view = getView(viewId);
view.setRating(rating);
return this;
}

public ViewHolder setRating(int viewId, float rating, int max) {
RatingBar view = getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}

public ViewHolder setTag(int viewId, Object tag) {
View view = getView(viewId);
view.setTag(tag);
return this;
}

public ViewHolder setTag(int viewId, int key, Object tag) {
View view = getView(viewId);
view.setTag(key, tag);
return this;
}

public ViewHolder setChecked(int viewId, boolean checked) {
Checkable view = (Checkable) getView(viewId);
view.setChecked(checked);
return this;
}

/**
* 关于事件的
*/
public ViewHolder setOnClickListener(int viewId,
View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}

public ViewHolder setOnTouchListener(int viewId,
View.OnTouchListener listener) {
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}

public ViewHolder setOnLongClickListener(int viewId,
View.OnLongClickListener listener) {
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
}

base/ItemViewDelegate.java

1
2
3
4
5
6
7
8
9
10
import android.view.View;

/**
* Created by zhy on 16/6/22.
*/
public interface ItemViewDelegate<T>{
public abstract int getItemViewLayoutId();
public abstract boolean isForViewType(T item, int position);
public abstract void convert(ViewHolder holder, T t, int position);
}

base/ItemViewDelegateManager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import androidx.collection.SparseArrayCompat;

/**
* Created by zhy on 16/6/22.
*/
public class ItemViewDelegateManager<T> {
SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();

public int getItemViewDelegateCount() {
return delegates.size();
}

public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> delegate) {
int viewType = delegates.size();
if (delegate != null) {
delegates.put(viewType, delegate);
viewType++;
}
return this;
}

public ItemViewDelegateManager<T> addDelegate(int viewType, ItemViewDelegate<T> delegate) {
if (delegates.get(viewType) != null) {
throw new IllegalArgumentException(
"An ItemViewDelegate is already registered for the viewType = "
+ viewType
+ ". Already registered ItemViewDelegate is "
+ delegates.get(viewType));
}
delegates.put(viewType, delegate);
return this;
}

public ItemViewDelegateManager<T> removeDelegate(ItemViewDelegate<T> delegate) {
if (delegate == null) {
throw new NullPointerException("ItemViewDelegate is null");
}
int indexToRemove = delegates.indexOfValue(delegate);

if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove);
}
return this;
}

public ItemViewDelegateManager<T> removeDelegate(int itemType) {
int indexToRemove = delegates.indexOfKey(itemType);

if (indexToRemove >= 0) {
delegates.removeAt(indexToRemove);
}
return this;
}

public int getItemViewType(T item, int position) {
int delegatesCount = delegates.size();
for (int i = delegatesCount - 1; i >= 0; i--) {
ItemViewDelegate<T> delegate = delegates.valueAt(i);
if (delegate.isForViewType(item, position)) {
return delegates.keyAt(i);
}
}
throw new IllegalArgumentException(
"No ItemViewDelegate added that matches position=" + position + " in data source");
}

public void convert(ViewHolder holder, T item, int position) {
int delegatesCount = delegates.size();
for (int i = 0; i < delegatesCount; i++) {
ItemViewDelegate<T> delegate = delegates.valueAt(i);

if (delegate.isForViewType(item, position)) {
delegate.convert(holder, item, position);
return;
}
}
throw new IllegalArgumentException(
"No ItemViewDelegateManager added that matches position=" + position + " in data " +
"source");
}


public int getItemViewLayoutId(int viewType) {
return delegates.get(viewType).getItemViewLayoutId();
}

public int getItemViewType(ItemViewDelegate itemViewDelegate) {
return delegates.indexOfValue(itemViewDelegate);
}

public ItemViewDelegate getItemViewDelegate(T item, int position) {
int delegatesCount = delegates.size();
for (int i = delegatesCount - 1; i >= 0; i--) {
ItemViewDelegate<T> delegate = delegates.valueAt(i);
if (delegate.isForViewType(item, position)) {
return delegate;
}
}
throw new IllegalArgumentException(
"No ItemViewDelegate added that matches position=" + position + " in data source");
}

public int getItemViewLayoutId(T item, int position) {
return getItemViewDelegate(item, position).getItemViewLayoutId();
}
}

调用