您的位置:首页 > 移动开发 > Android开发

Android 真正的“万能”Adapter

2016-04-19 13:56 519 查看
最近看到不少封装Adapter的库,但是都感觉不够方便。今天给大家介绍一个真正的“万能”Adapter(源码地址),

精髓就在于一个Adapter同时适用于RecyclerView、ListView、GridView、Spinner等。



源码结构图.png

主要特性

减少大量代码!减少大量代码!减少大量代码!(重说三)
支持header和footer。
支持RecyclerView的item点击事件。
隐藏ViewHolder相关的所有代码。
一个SuperAdapter同时支持
BaseAdapter
RecyclerView.Adapter

封装Adapter数据源变动操作。

如何使用

如果是个简单布局的Adapter,可以简写为如下示例代码:

public class SingleAdapter extends SuperAdapter<MockModel> {
public SingleAdapter(Context context, List<MockModel> list, int layoutResId) {
super(context, list, layoutResId);
}

@Override
public void onBind(SuperViewHolder holder, int viewType, int position, MockModel item) {
holder.setText(R.id.tv_name, item);
}
}


可以看出除了构造方法,只需要重写一个
onBind()
方法就够了。

然后在Activity(or Fragment)中调用:

mSingleAdapter = new RecyclerSingleAdapter(context, list, R.layout.your_item);
recyclerView.setAdapter(mSingleAdapter);


其中
SuperViewHolder
为通用的holder封装类,提供了一系列的便捷方法(
ChainSetter
),而且可以链式调用,如:



ChainSetter部分方法.png

还可以使用
getView(int viewId)
来确定一个item的view:

@Override
public void onBind(SuperViewHolder holder, int viewType, int position, String item) {
holder.setText(R.id.tv_name, item);
ImageView img = holder.getView(R.id.iv_portrait);
img.setImageResource(resId);
}


当然也支持多item布局,需要提供一个
IMulItemViewType<T>
接口:

public class MultipleAdapter extends SuperAdapter<MockModel> {
public MultipleAdapter(Context context, List<MockModel> list, IMulItemViewType<MockModel> multiItemViewType) {
super(context, list, multiItemViewType);
}

@Override
public void onBind(SuperViewHolder holder, int viewType, int position, MockModel item) {
switch (viewType) {
case 0:
holder.setText(R.id.tv_name, item.getName());
break;
case 1:
holder.setText(R.id.tv_name, item.getName());
holder.setImageResource(R.id.iv_portrait, R.mipmap.ic_launcher);
holder.setText(R.id.tv_age, String.valueOf(item.getAge()));
break;
}
}
}


然后调用(注意构造方法的参数与单布局的区别):

multiAdapter = new MultipleAdapter(getContext(), list, new IMulItemViewType<MockModel>() {
@Override
public int getItemViewType(int position, MockModel mockModel) {
if (position % 2 == 0) {
return 0;
}
return 1;
}

@Override
public int getLayoutId(int viewType) {
if (viewType == 0) {
return R.layout.item_type1;
}
return R.layout.item_type2;
}

@Override
public int getViewTypeCount() {
return 2;
}
});
recyclerView.setAdapter(mMultiAdapter);


如果使用的是RecyclerView,在使用多布局时,还可以使用
SimpleMulItemViewType
类(继承自
IMulItemViewType
),

因为
getViewTypeCount()
方法仅在使用ListView、GridView等控件时是必须提供的:

mAdapter = new MultipleAdapter(getContext(), models, new SimpleMulItemViewType<MockModel>() {
@Override
public int getItemViewType(int position, MockModel mockModel) {
if (position % 2 == 0) {
return 0;
}
return 1;
}

@Override
public int getLayoutId(int viewType) {
if (viewType == 0) {
return R.layout.item_type1;
}
return R.layout.item_type2;
}
});
recyclerView.setAdapter(mAdapter);


如果不想在创建Adapter时提供IMulItemViewType接口,也可以在Adapter中重写
offerMultiItemViewType()
方法:

@Override
protected IMulItemViewType<MockModel> offerMultiItemViewType() {
return new IMulItemViewType<MockModel>() {
@Override
public int getViewTypeCount() {
return 2;
}

@Override
public int getItemViewType(int position, MockModel mockModel) {
if (position % 2 == 0) {
return 0;
}
return 1;
}

@Override
public int getLayoutId(int viewType) {
if (viewType == 0) {
return R.layout.item_type1;
}
return R.layout.item_type2;
}
};
}


然后在创建Adapter时提供
null


multiAdapter = new MultipleAdapter(context, list, null);


至于header和footer的使用,就更简单啦!
adapter.addHederView(view)
就可以添加一个Header了,你可以使用的全部api如下:



Header和Footer相关的api.png

源码地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: