开始之前
有段时间没有写博客了,今天仔细学习了一下封装RecyclerView对Adapter和ViewHolder的封装,所以抓紧时间记录一下
导包之类的基本使用我就不说了,直接进入今天的主题
封装ViewHolder
/**
* Created by lulu on 2017/1/22.
* RecyclerView.ViewHolder 的公共类,做了一些封装。目的:
* ViewHolder 与 Adapter 解耦,和 ViewHolder 相关的逻辑都放到 ViewHolder 里边,避免 Adapter 有相关逻辑
*/
public abstract class CommonRecyclerViewHolder<T> extends RecyclerView.ViewHolder {
public CommonRecyclerViewHolder(Context context, ViewGroup root, int layoutRes) {
super(LayoutInflater.from(context).inflate(layoutRes, root, false));
}
/**
* 用给定的 data 对 holder 的 view 进行赋值
*/
public abstract void bindData(T t);
/**
* 因为 CommonRecyclerAdapter 里边无法对于未知类型的 Class 进行实例化
* 所以需要如果想用 CommonRecyclerAdapter,必须要在对应的 CommonViewHolder 实例化一个 HOLDER_CREATOR
* 注意:public static ViewHolderCreator HOLDER_CREATOR,名字与修饰符都不能更改,否则有可能引发失败
*
* 如果不使用 CommonListAdapter,则不需要实例化 ViewHolderCreator
*
* @param <VH>
*/
public interface ViewHolderCreator<VH extends CommonRecyclerViewHolder> {
VH createByViewGroupAndType(ViewGroup parent, int viewType);
}
ViewHolderCreator用于在CommonRecyclerAdapter中创建ViewHolder实例用
封装Adapter
/**
* Created by lulu on 2017/1/22.
* 单类型 item 的 RecyclerView 对应的 Adapter
*/
public class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<CommonRecyclerViewHolder> {
private static HashMap<String, CommonRecyclerViewHolder.ViewHolderCreator> creatorHashMap = new HashMap<>();
private Class<?> vhClass;
//数据源
protected List<T> dataList = new ArrayList<>();
public CommonRecyclerAdapter() {
super();
}
public CommonRecyclerAdapter(Class<?> vhClass) {
this.vhClass = vhClass;
}
/**
* 设置数据,会清空之前的数据
*
* @param datas
*/
public void setDataList(List<T> datas) {
dataList.clear();
if (datas != null) {
dataList.addAll(datas);
}
}
/**
* 添加数据,默认在最后插入,以前数据保留
*
* @param datas
*/
public void addDataList(List<T> datas) {
dataList.addAll(datas);
}
@Override
public CommonRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (vhClass != null) {
try {
//不设置holder直接抛出异常
throw new IllegalArgumentException("please use CommonListAdapter(Class<VH> vhClass)");
} catch (Exception e) {
e.printStackTrace();
}
}
CommonRecyclerViewHolder.ViewHolderCreator<?> creator = null;
if (creatorHashMap.containsKey(vhClass.getName())) {
creator = creatorHashMap.get(vhClass.getName());
} else {
try {
creator = ((CommonRecyclerViewHolder.ViewHolderCreator) vhClass.getField("HOLDER_CREATOR").get(null));
creatorHashMap.put(vhClass.getName(), creator);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
if (creator != null) {
return creator.createByViewGroupAndType(parent, viewType);
} else {
throw new IllegalArgumentException(vhClass.getName() + " HOLDER_CREATOR should be instantiated");
}
}
@Override
public void onBindViewHolder(CommonRecyclerViewHolder holder, int position) {
if (position >= 0 && position < dataList.size()) {
holder.bindData(dataList.get(position));
}
}
@Override
public int getItemCount() {
return dataList.size();
}
}
内部的HashMap防止多次创建ViewHolder
至此封装完毕,接下来做个简单的测试
MyViewHolder.java
/**
* Created by lulu on 2017/1/22.
* 测试ViewHolder
*/
public class MyViewHolder extends CommonRecyclerViewHolder<String> {
private TextView mTextView;
public MyViewHolder(ViewGroup root) {
super(root.getContext(), root, android.R.layout.simple_expandable_list_item_1);
initView();
}
private void initView() {
mTextView = (TextView) itemView.findViewById(android.R.id.text1);
}
public static ViewHolderCreator HOLDER_CREATOR = new ViewHolderCreator<MyViewHolder>() {
@Override
public MyViewHolder createByViewGroupAndType(ViewGroup parent, int viewType) {
return new MyViewHolder(parent);
}
};
@Override
public void bindData(String str) {
mTextView.setText(str);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
CommonRecyclerAdapter<String> adapter = new CommonRecyclerAdapter<>(MyViewHolder.class);
List<String> mList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
mList.add("测试数据 " + i);
}
recycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recycler.setAdapter(adapter);
adapter.setDataList(mList);
}
}
截图
致谢
参考 LeanCloud中的源码部分
有啥错误还请大神们指出^v^