ObjectAdapter 扩展RecyclerView Adapter的方式

前言

起因,随着业务的开展,我们的Feed列表有时会增加好多的卡片类型,而过多的卡片就会引发过多的 ViewHolder,ViewType 造成Adapter路基冗杂。那么本篇博客就是基于这个问题做的Adapter 扩展。

扩展对比

扩展前

Activity:

1
2
recyclerView.setAdapter(new OldAdapter(this));
recyclerView.setLayoutManager(new LinearLayoutManager(this));

Adapter:

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
public class OldAdapter extends RecyclerView.Adapter {
private Context mContext;
private LayoutInflater mInflater;
private List<IndexTypeEnum> mData;
public OldAdapter(Context context) {
this.mContext = context;
this.mInflater = LayoutInflater.from(mContext);
this.mData = new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == 1) {
view = mInflater.inflate(R.layout.item_frist, parent, false);
} else if (viewType == 2) {
view = mInflater.inflate(R.layout.item_second, parent, false);
} else {
view = mInflater.inflate(R.layout.item_thrid, parent, false);
}
return new InnerViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// ...do
}
@Override
public int getItemCount() {
return mData.size();
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return 1;
} else if (position == 1) {
return 2;
} else {
return 3;
}
}
public void setData(List<IndexTypeEnum> data) {
this.mData = data;
notifyDataSetChanged();
}
public void add(IndexTypeEnum indexTypeEnum, int pos) {
mData.add(pos, indexTypeEnum);
notifyItemChanged(pos);
}
public void remove(IndexTypeEnum indexTypeEnum, int pos) {
mData.remove(pos);
notifyItemChanged(pos);
}
public void move(int fromPosition, int toPosition) {
IndexTypeEnum indexTypeEnum = mData.get(fromPosition);
mData.set(fromPosition, mData.get(toPosition));
mData.set(toPosition, indexTypeEnum);
notifyItemMoved(fromPosition, toPosition);
}
public static class InnerViewHolder extends RecyclerView.ViewHolder {
public InnerViewHolder(View itemView) {
super(itemView);
}
}
}

添加:

1
adapter.add(1, FRIST);

删除:

1
adapter.remove(1);

移动:

1
adapter.move(1,2);

扩展后

Activity:

1
2
3
4
5
6
7
8
presenterSelector = new ZhihuPresenterSelector(this);
objectAdapter = new ArrayObjectAdapter(presenterSelector);
recyclerView.setObjectAdapter(objectAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
for (IndexTypeEnum indexTypeEnum : data) {
objectAdapter.add(indexTypeEnum);
}

PresenterSelector:

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
public class ZhihuPresenterSelector extends PresenterSelector {
private final ArrayList<Presenter> mPresenters = new ArrayList<>();
private FristPresenter fristPresenter;
private SecondPresenter secondPresenter;
private ThridPresenter thridPresenter;
public ZhihuPresenterSelector(Context context) {
fristPresenter = new FristPresenter(context);
secondPresenter = new SecondPresenter(context);
thridPresenter = new ThridPresenter(context);
containerPresenter = new ContainerPresenter(context);
mPresenters.add(fristPresenter);
mPresenters.add(secondPresenter);
mPresenters.add(thridPresenter);
}
@Override
public Presenter getPresenter(Object item) {
IndexTypeEnum indexRow = (IndexTypeEnum) item;
switch (indexRow) {
case FRIST:
return fristPresenter;
case SECOND:
return secondPresenter;
case THRIED:
return thridPresenter;
default:
return fristPresenter;
}
}
@Override
public Presenter[] getPresenters() {
return mPresenters.toArray(new Presenter[mPresenters.size()]);
}
}

Presenter:

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
public class FristPresenter extends Presenter {
private Context mContext;
private LayoutInflater mInflater;
public FristPresenter(Context context) {
this.mContext = context;
this.mInflater = ((Activity) context).getLayoutInflater();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
View view = mInflater.inflate(R.layout.item_frist, parent, false);
return new InnerViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item, int position) {
}
@Override
public void onUnBindViewHolder(ViewHolder viewHolder) {
}
protected class InnerViewHolder extends ViewHolder {
public InnerViewHolder(View view) {
super(view);
}
}
}

添加:

1
objectAdapter.add(1, indexTypeEnum)

删除:

1
2
objectAdapter.remove(indexTypeEnum1);
objectAdapter.remove(1);

移动:

1
objectAdapter.move(1,2);

小节

这里我们可以看到,优化前Adapter是很冗杂的,但优化后,我们可以按职责详细划分这里的业务逻辑.

1.我们这里通过 PresenterSelector 来总结当前所有的卡片种类(Presenter).

2.将我们不同的卡片业务逻辑划分到对应的 Presenter.

3.关于基本操作全部封装在 ObjectAdapter.

How to use?

1
2
3
4
5
6
7
8
repositories {
// ...
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.jarvis.library:ObjectAdapter:1.0'
}