前言
早期文章 , 如今搬运过来 , RecyclerView用法相信都会,这里主要介绍一下简单的封装。
不管我们是在使用早期的ListView
还是使用强大的RecyclerView
,我们都需要去实现其控件的Adapter ,将数据与控件绑定起来 。不管是ListViewAdapter
还是RecyclerViewAdapter
,都需要我们实现大量的方法 ,重复的去编写相同的操作 ,为了减少不必要的编码 ,就需要将Adapter的共性抽取出来 ,做成一个通用的Adapter ,以后需要实现Adapter ,只需要继承我们自己写的Adapter就OK了 。
分析
不管是我们的ListViewAdapter还是RecyclerViewAdapter ,其主要有两点 :
第一、 外界提供给我们的数据源 , 这个是变化的 。
第二、 外界提供给我们的布局文件资源(也可拓展为布局View) , 这个也是变化,需要传递的参数
另 : RecyclerView需要我们自己实现Item的各种事件
如果布局中需要Context ,也可以作为参数传入 ,创建多个构造函数
编写 :
要封装RecyclerView.Adapter,就需要搞清楚,RecyclerViewAdapter主要实现三个方法 ,onCreateViewHolder
、onBindViewHolder
、getItemCount
,还有一个ViewHolder类 。我们来分析分析 , 这几个方法和类 。
onCreateViewHolder
主要构件RecyclerView
每个Item布局对象 ,与ViewHolder关联 ,达到复用视图的效果,并传递给 onBindViewHolder
,因为我们的布局对象都是View , 所以这个地方 , 我们可以根据传递进来的资源文件infalter成一个View ,亦或是传进来的View,再与ViewHolder关联 , 此处我们就可以对外屏蔽掉了 。
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
false);
ViewHolder viewHolder = new ViewHolder(view);
// 初始化Item事件监听
initOnItemListener(viewHolder);
return viewHolder;
}
onBindViewHolder
主要讲数据与ViewHolder里面的控件相关联 ,因为我要实现不同RecyclerView Item的数据显示 ,所以这个地方不能写死 ,需要我们根据情况 ,将数据绑定到不同的控件上面 , 这里需要抽象方法传递出来数据 , 让继承我们的Adapter做操作
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
Object o = mItems.get(position);
convertView((ViewHolder) holder,o);
}
getItemCount
@Override
public int getItemCount()
{
return mItems.size();
}
返回我们的Item总条数
ViewHolder
将ViewHolder类抽取出来,主要是为了更加方便的进行View组件的操作,这个类 ,主要是为我们的控件复用服务 ,因为在Adapter每个Item与ViewHolder关联 ,所以在此类中 , 我们可以做一些获取控件的简便操作 。
private View mConvertView;
private SparseArray<View> mViews;
public ViewHolder(View itemView)
{
super(itemView);
mViews = new SparseArray<>() ;
mConvertView = itemView ;
}
/**
* 根据资源获取View对象
* @param res
* @param <T>
* @return
*/
public <T extends View> T getView(@IdRes int res) {
View view = mViews.get(res);
if (view == null) {
view = mConvertView.findViewById(res) ;
mViews.put(res,view);
}
return (T) view;
}
完整Adapter代码
/**
* Created by Zeno on 2016/6/8.
*
* 简介 :
* 抽象类的抽取 ,主要是抽取一些有共性的方法和参数 。
*
* 分析:
* 不管是ListView还是RecyclerView ,主要有两个点需要实现:
* 第一 :外界提供的数据源
* 第二 :外界提供的布局
* 这两个点是明确从外部传入的 ,所以首先这两个点不能固定 ,需要作为参数从外部传入
* 如果有一些资源需要用到上下文 ,还需要传入Context
*
*
*/
public abstract class SimpleBaseRecyclerAdapter extends RecyclerView.Adapter
{
// each item layout res
private int mItemLayoutRes;
// total item data set
private List<?> mItems;
private ItemClickListener mItemClickListener ;
private ItemLongClickListnener mItemLongClickListnener ;
public SimpleBaseRecyclerAdapter(@LayoutRes int mItemLayoutRes, List<?> items)
{
this.mItemLayoutRes = mItemLayoutRes;
// 如果没有传入的数据 ,则自动创建一个空的集合 ,防止报空指针
this.mItems = items ==null ? new ArrayList<>() : items;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
false);
ViewHolder viewHolder = new ViewHolder(view);
// 初始化Item事件监听
initOnItemListener(viewHolder);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
Object o = mItems.get(position);
convertView((ViewHolder) holder,o);
}
@Override
public int getItemCount()
{
return mItems.size();
}
public abstract void convertView(ViewHolder viewHolder, Object itemObj) ;
/**
* init set item view listener
* @param holder
*/
private void initOnItemListener(final RecyclerView.ViewHolder holder) {
if (mItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Object o = mItems.get(holder.getLayoutPosition());
mItemClickListener.onItemClick(v,o ,holder.getLayoutPosition());
}
});
}
if (mItemLongClickListnener != null) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{
Object o = mItems.get(holder.getLayoutPosition());
mItemLongClickListnener.onItemLongClick(v,o,holder.getLayoutPosition());
return true;
}
});
}
}
/**
* set item view click
* @param listener
*/
public void setOnItemClickListener(ItemClickListener listener) {
mItemClickListener = listener ;
}
/**
* set item view long click
* @param listener
*/
public void setOnItemLongClickListener(ItemLongClickListnener listener) {
mItemLongClickListnener = listener ;
}
public interface ItemClickListener {
void onItemClick(View view ,Object itemObj , int position) ;
}
public interface ItemLongClickListnener {
void onItemLongClick(View view ,Object itemObj, int position) ;
}
}
完整ViewHolder代码
/**
* Created by Zeno on 2016/6/8.
*
* ViewHolder主要是做一些与控件布局有关的操作 ,所有我们可以在这边简化一下获取控件对象的代码
*/
public class ViewHolder extends RecyclerView.ViewHolder
{
private View mConvertView;
private SparseArray<View> mViews;
public ViewHolder(View itemView)
{
super(itemView);
mViews = new SparseArray<>() ;
mConvertView = itemView ;
}
/**
* 根据资源获取View对象
* @param res
* @param <T>
* @return
*/
public <T extends View> T getView(@IdRes int res) {
View view = mViews.get(res);
if (view == null) {
view = mConvertView.findViewById(res) ;
mViews.put(res,view);
}
return (T) view;
}
/**
* 提供TextView和Button设置文本简化操作
* @param idRes
* @param charSequence
* @return
*/
public ViewHolder setText(@IdRes int idRes , CharSequence charSequence) {
View view = getView(idRes);
if (view instanceof TextView) {
((TextView)view).setText(charSequence);
}else if (view instanceof Button) {
((Button)view).setText(charSequence);
}
return this ;
}
/**
* 提供TextView和Button设置文本颜色简化操作
* @param idRes
* @param color
* @return
*/
public ViewHolder setTextColor(@IdRes int idRes , int color) {
View view = getView(idRes);
if (view instanceof TextView) {
((TextView)view).setTextColor(color);
}else if (view instanceof Button) {
((Button)view).setTextColor(color);
}
return this ;
}
/**
* 设置指定ViewId的背景颜色
* @param idRes
* @param color
* @return
*/
public ViewHolder setBackgroundColor(@IdRes int idRes , int color) {
View view = getView(idRes);
view.setBackgroundColor(color);
return this;
}
/**
* 设置ImageView显示图片
* @param idRes
* @param res
* @return
*/
public ViewHolder setImageResoruce(@IdRes int idRes , @DrawableRes int res) {
View view = getView(idRes);
if (view instanceof ImageView) {
((ImageView)view).setImageResource(res);
}
return this ;
}
/**
* 设置指定控件ID的点击事件
* @param idRes
* @param listener
* @return
*/
public ViewHolder setOnClickListener(@IdRes int idRes , View.OnClickListener listener) {
View view = getView(idRes);
view.setOnClickListener(listener);
return this;
}
/**
* 设置指定控件ID的长按事件
* @param idRes
* @param listener
* @return
*/
public ViewHolder setOnLongClickListener(@IdRes int idRes , View.OnLongClickListener listener) {
View view = getView(idRes);
view.setOnLongClickListener(listener);
return this;
}
/**
* 设置指定控件的TAG
* @param idRes
* @param tag
* @return
*/
public ViewHolder setTag(@IdRes int idRes , Object tag) {
View view = getView(idRes);
view.setTag(tag);
return this;
}
/**
* 获取指定控件的TAG
* @param idRes
* @return
*/
public Object getTag(@IdRes int idRes) {
View view = getView(idRes);
return view.getTag() ;
}
}
网友评论