在Android开发中,会经常用到RecyclerView来显示数据,数据的绑定使用到Adapter,原声的Adapter需要些很多重复代码,今天写了一个通用的代码来实现适配器绑定数据,减少代码量。
通用Adapter的功能:
1、FooterView和headerView的显示
2、停止滚动屏幕,再去加载数据
下面是代码的详解:
1、通用的ViewHolder
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
private SparseArray arrayView;
public RecyclerViewHolder(View itemView) {
super(itemView);
arrayView = new SparseArray<>();
}
/**
* 通过填写的itemId来获取具体的View的对象
* @param itemId R.id.***
* @param 必须是View的子类
* @return
*/
public T getView(int itemId){
//arrayVie类似于Map容器,get(key)取出的是value值
View mView = arrayView.get(itemId);
if(mView == null){
//实例化具体的View类型
mView = itemView.findViewById(itemId);
arrayView.put(itemId,mView);
}
return (T) mView;
}
/**
* 设置TextView的内容
* @param itemId
* @param text
*/
public void setText(int itemId,String text){
TextView tv = getView(itemId);
tv.setText(text);
}
/**
* 设置图片
* @param itemId
* @param imageId
*/
public void setBitmapImage(int itemId,int imageId){
ImageView iv = getView(itemId);
iv.setImageResource(imageId);
}
}
1、主要方法:getView(int itemId) 传入的是具体的id,
2、使用SparseArray中的get方法获取View实例,如果不存在,那么就findViewByid(itemId)获取View实例。
3、最后,为一些基本的空间提供设置内容的方法。如setText()为TextView设置内容,setBitmapImage(int id)为图片设置内容。
2、BaseRecyclerAdapter
public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter{
private static final String TAG = "BaseRecyclerAdapter--->";
private static final int TYPE_HEAD = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOT = 2;
private boolean isScrolling = true; //false表示滑动,true表示不滑动
private View headerView,footerView; //头和尾的view
private List lists; //传入的集合。
private int totalList;
private int itemLayoutId; //设置Layout的id。
private Context cxt;
private OnItemViewClickListener onItemViewClickListener;
public interface OnItemViewClickListener{
//设置item中某个view的点击事件
void onItemViewClick(RecyclerViewHolder view,int position);
}
public void setonItemViewClickListener(OnItemViewClickListener listener){
this.onItemViewClickListener = listener;
}
public BaseRecyclerAdapter(RecyclerView view,List list,int itemLayoutId){
this.lists = list;
this.itemLayoutId = itemLayoutId;
this.cxt = view.getContext();
view.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//设置如果Recycler停止滑动,去绑定更新数据。
if(newState == RecyclerView.SCROLL_STATE_IDLE){
//表示停止滑动
isScrolling = true;
Log.i(TAG,isScrolling+"停止滚动");
}else{
//正在滑动
isScrolling = false;
Log.i(TAG,isScrolling+"正在滚动....");
}
//将上面代码改写成这样。
// isScrolling = (newState == RecyclerView.SCROLL_STATE_IDLE);
if(isScrolling){ //为true时候表示停止滑动操作,去更新数据
notifyDataSetChanged();
}
super.onScrollStateChanged(recyclerView,newState);
}
});
}
public void setFooterView(View view){
this.footerView = view;
}
public void setHeaderView(View view){
this.headerView = view;
}
/**
* 创建RecyclerView里面的itemView。
* @param parent
* @param viewType
* @return
*/
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_HEAD && headerView !=null){
return new RecyclerViewHolder(headerView);
}
if(viewType == TYPE_FOOT && footerView!=null){
return new RecyclerViewHolder(footerView);
}
View view = LayoutInflater.from(cxt).inflate(itemLayoutId,parent,false);
return new RecyclerViewHolder(view);
}
/**
* 绑定每一个itemView的具体数据
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
if(getItemViewType(position) != TYPE_ITEM){
//如果不是正常的Item,就不去绑定数据
return;
}
Log.i(TAG,"bindView---"+position);
//抽象方法,让子类去具体的实现
int p = getRealPosition(position);
bindConvert(holder,p,lists.get(p),isScrolling);
if(onItemViewClickListener!=null){
onItemViewClickListener.onItemViewClick(holder,p);
}
}
private int getRealPosition(int position){
return headerView ==null ? position : position-1;
}
public abstract void bindConvert(RecyclerViewHolder holder, int position, T item, boolean isScrolling);
/**
* 判断有多少个list.size()
* @return
*/
@Override
public int getItemCount() {
if(lists == null){
return 0;
}
if(headerView!=null && footerView!=null){
//头尾都不为空
totalList = lists.size()+2;
}else if(headerView ==null && footerView ==null){
//头尾都为空
totalList = lists.size();
}else{
//头尾有一个不为空
totalList = lists.size()+1;
}
return totalList;
}
@Override
public int getItemViewType(int position) {
if(position == 0 && headerView !=null){
//表示第一个item,并且headerView不为空
return TYPE_HEAD;
}
if(position+1 == getItemCount() && footerView !=null){
//表示最好一个item,并且footerView不为空
return TYPE_FOOT;
}
return TYPE_ITEM;
}
}
1、该抽象类, 首先继承了RecyclerView.Adapter类,
2、实现VH onCreateViewHolder(ViewGroup parent, int viewType)、
实例化具体的ViewHolder类
void onBindViewHolder(VH holder, int position);
绑定具体的数据。
int getItemCount()三个抽象方法。
3、重写int getItemViewType(int position)方法。
4、定义一个抽象类,让继承该类的子类去实现方法。
主要是绑定具体的View数据。
public abstract void bindConvert(RecyclerViewHolder holder, int position, T item, boolean isScrolling);
3、子类Adapter实现BaseRecyclerAdapter方法
public class TextAdapter extends BaseRecyclerAdapter<String> {
public TextAdapter(RecyclerView view, List list) {
super(view, list, R.layout.recyclerview_item);
}
@Override
public void bindConvert(RecyclerViewHolder holder, int position, String item, boolean isScrolling) {
if(isScrolling) {
//不滑动的时候去加载数据
holder.setText(R.id.info_tv, "第" + position + "条数据");
}
}
}
isScrolling来自于父类的方法,主要是滑动的监听,用户滑动屏幕时候,不去加载数据,停止滑动时再去加载数据。
view.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//设置如果Recycler停止滑动,去绑定更新数据。
if(newState == RecyclerView.SCROLL_STATE_IDLE){
//表示停止滑动
isScrolling = true;
Log.i(TAG,isScrolling+"停止滚动");
}else{
//正在滑动
isScrolling = false;
Log.i(TAG,isScrolling+"正在滚动....");
}
//将上面代码改写成这样。
// isScrolling = (newState == RecyclerView.SCROLL_STATE_IDLE);
if(isScrolling){ //为true时候表示停止滑动操作,去更新数据
notifyDataSetChanged();
}
super.onScrollStateChanged(recyclerView,newState);
}
});
源码下载地址:http://download.csdn.net/detail/u011521890/9488936