EasyAdapter

常规写法的探讨

常规的写法,为了使用 RecyclerView,必须指定一个 adapter 和 一个 LayoutManager。其中自定义的 adapter 必须继承自 RecyclerView.Adapter,其中必须实现几个接口:

  • public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
    在这个接口当中根据类别创建 ViewHolder 和 inflate layout,要是有多个item需要写一堆if-else

  • public void onBindViewHolder(ItemViewHolder viewHolder, int position)或者

    public void onBindViewHolder(TRealViewHolder holder, int position, List<Object> payloads)<br />
    


    在这个接口当中根据位置 position 取出对应的数据,并用于刷新 viewHolder 里面的 UI

  • public int getItemCount()
    在这个接口当中根据位置保存的数据数量指定列表控件 item 的数量

因此可以看出

  1. 👆以上几个接口的套路都是固定的,可以做一层统一的封装
  2. 其次 onCreateViewHolderonBindViewHolder 还不足以清晰直观的表达 itemView 是创建还是复用
  3. ModelViewHolder 之间的映射关系没有做硬性规定

针对改进

  • 注解的方式加载布局
  • 将数据和视图分离
  • 更加清晰的holder复用

1、注解的方式加载布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@EasyViewHolderAnnotation(resId = R.layout.item_infoone)
public class InfoViewViewHolderOne extends BaseEasyViewHolder<ItemOneData> {

public InfoViewViewHolderOne(Context context, View itemView, RecyclerView recyclerView) {
super(context, itemView, recyclerView);
}

@Override
public void inflate() {
//初始化控件
}

@Override
public void refresh(EasyAdapterItem<ItemOneData> tAdapterItem) {
if (tAdapterItem == null || tAdapterItem.getDataModel() == null) {
return;
}
ItemOneData model = tAdapterItem.getDataModel();
//使用datamodel刷新 UI
}
}

2、数据与视图分离

举个例子 上面的InfoViewViewHolderOne需要使用 ItemDataModel的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class InfoViewHolderItemOne implements EasyAdapterItem<ItemOneData> {

private ItemOneData mItemOneData;

public InfoViewHolderItemOne(ItemOneData goodInfo) {
mItemOneData = goodInfo;
}

@Override
public int getViewType() {
return VIEW_TYPE_INFO_ONE;
}

@Override

public int getId() {
return 0;
}

@Override
public ItemOneData getDataModel() {
return mItemOneData;
}
}

绑定是通过一个map来进行数据数据绑定,这样复用更加清晰

1
2
3
4
5
private final SparseArray<Class<? extends BaseEasyViewHolder>> viewHolders = new SparseArray<Class<? extends BaseEasyViewHolder>>() {
{
put(ViewItemType.VIEW_TYPE_INFO_ONE, InfoViewViewHolderOne.class);
}
};

整体设计

image.png

使用

结合示例代码

1、定义 ViewItemType 类型枚举值:
2、定义具体 InfoViewViewHolderOne class和对应数据 ItemOneData 类型
3、绑定holder和viewitemType

1
2
3
4
5
6
private final SparseArray<Class<? extends BaseEasyViewHolder>> viewHolders = new SparseArray<Class<? extends BaseEasyViewHolder>>() {
{
put(ViewItemType.VIEW_TYPE_INFO_ONE, InfoViewViewHolderOne.class);
put(ViewItemType.VIEW_TYPE_INFO_TWO, InfoViewViewHolderTwo.class);
}
};

4、初始化 数据源 List mTAdapterItems

1
private final List<EasyAdapterItem> mAdapterItems = new ArrayList<>();

5、将Adapter设置给 RecyclerView

技术点

  • 泛型、抽象
  • 注解
  • 反射

最后

由于使用到了反射去创建viewHolder,因此继承BaseEasyViewHolder时候注意防止混淆

1
2
3

-keep class me.xsfdev.easyadapterlib.base.** {*;}
-keep class * extends me.xsfdev.easyadapterlib.base.BaseEasyViewHolder{*;}
0%