封装Recycleview.Adapter使Recycleview具有加载更多,item点击事件等功能
2015-07-29 23:48
465 查看
Recycleview简介:
类似Recycleview使用的文章很多,这里简单介绍一下:RecyclerView是support-v7包中的新组件,自带布局复用与ViewHolder,Recycleview不关心UI的显示方式,由LayoutManager实现类控制显示方式。如果你还没使用过Recycleview,建议先写一个ListView样式的Recycleview
demo.
需要解决的问题:
1.下拉刷新,上拉加载是ListView中最常用的功能。下拉刷新可以使用V7包中SwipeRefreshLayout等实现,加载更多如何实现呢?2.列表显示中多种布局也是常见的功能,Recycleview如何实现呢。
3.使用时会不会很失望,怎么没有item点击事件呢?
一个个来解决:
[b]废话少说,放码过来:
[/b]
public abstract class MCyclerAdapter<T>extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected List<T> list; protected Context context; protected LayoutInflater inflater; private final static int FOOT_TYPE = 99; /** * 设置自己的底部加载更多的布局 * @param customFootView */ public void setCustomFootView(View customFootView) { isLoadMore = true; this.customFootView = customFootView; } private View customFootView; public boolean isMultiType() { return isMultiType; } public boolean isLoadMore() { return isLoadMore; } /** * 设置是否底部显示加载更多,默认不显示 * @param isLoadMore */ public void setIsLoadMore(boolean isLoadMore) { this.isLoadMore = isLoadMore; } private boolean isLoadMore = false; /** * 设置是否是多种布局,默认单一布局 * @param isMultiType */ public void setIsMultiType(boolean isMultiType) { this.isMultiType = isMultiType; } private boolean isMultiType = false; public MCyclerAdapter(List<T> list,Context context){ this.list = list; this.context = context; inflater = LayoutInflater.from(context); } /** * 如果你的item布局是多种,需要复写这个方法 * @param postion * @return */ public abstract int getDisplayType(int postion); @Override public int getItemViewType(int position) { if (isLoadMore&&position==getItemCount()-1){ return FOOT_TYPE; } if (isMultiType){ return getDisplayType(position); } return super.getItemViewType(position); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (isLoadMore&&viewType==FOOT_TYPE){ View view = null; if (customFootView!=null){ view = customFootView; }else { view = inflater.inflate(R.layout.bottom_progressbar,parent,false); } return new FootHolder(view); } return onCreateDisplayHolder(parent, viewType); } public abstract RecyclerView.ViewHolder onCreateDisplayHolder(ViewGroup parent,int viewType); @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (isLoadMore&&position==getItemCount()-1){ if (moreListerner!=null){ handler.sendEmptyMessageDelayed(11,300); } retu 4000 rn; } onBindData(holder,position); } public abstract void onBindData(RecyclerView.ViewHolder holder, int position); /** * 返回列表长度 * @return */ @Override public int getItemCount() { if (isLoadMore) return list==null||list.size()==0?0:list.size()+1; return list==null||list.size()==0?0:list.size(); } class FootHolder extends RecyclerView.ViewHolder{ public FootHolder(View itemView) { super(itemView); } } public OnLoadMoreListerner getMoreListerner() { return moreListerner; } public void setMoreListerner(OnLoadMoreListerner moreListerner) { this.moreListerner = moreListerner; } private OnLoadMoreListerner moreListerner; public interface OnLoadMoreListerner{ public void loadMore(); } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); moreListerner.loadMore(); } }; /** * 如果你需要有item的点击事件,你自己的ViewHolder extends BaseHolder */ class BaseHolder extends RecyclerView.ViewHolder{ public CycleItemClilkListener getCycleItemClilkListener() { return cycleItemClilkListener; } public void setCycleItemClilkListener(CycleItemClilkListener cycleItemClilkListener) { this.cycleItemClilkListener = cycleItemClilkListener; } private CycleItemClilkListener cycleItemClilkListener; public BaseHolder(View itemView,CycleItemClilkListener listener) { super(itemView); cycleItemClilkListener = listener; itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (cycleItemClilkListener!=null){ cycleItemClilkListener.onCycleItemClick(v,getPosition()); } } }); } } public interface CycleItemClilkListener{ void onCycleItemClick(View view,int position); } }
1.思路是滚动到末尾位置时加载一个Foot布局,isLoadMore用于标记是否需要加载更多默认不需要,
getItemCount返回长度,注意需要加载更多时长度是数据长度+1
public int getItemViewType(int position) { if (isLoadMore&&position==getItemCount()-1){ return FOOT_TYPE; } if (isMultiType){ return getDisplayType(position); } return super.getItemViewType(position); }
@Override public int getItemCount() { if (isLoadMore) return list==null||list.size()==0?0:list.size()+1; return list==null||list.size()==0?0:list.size(); }
然后就要写FootHolder
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (isLoadMore&&position==getItemCount()-1){ if (moreListerner!=null){ handler.sendEmptyMessageDelayed(11,300); } return; } onBindData(holder,position); }2.多种布局与加载更多一个思路,这里我定义了一个抽象方法getDisplayType方便子类去实现
if (isMultiType){ return getDisplayType(position); }3.因为在构造ViewHolder时,rootView将作为一个必传参数传递进来,所以我们只需要拿到rootView并给其绑定点击监听事件即可。这里我定义了一个带有点击事件的ViewHolder,需要时直接继承BaseViewHolder
class BaseHolder extends RecyclerView.ViewHolder{ public CycleItemClilkListener getCycleItemClilkListener() { return cycleItemClilkListener; } public void setCycleItemClilkListener(CycleItemClilkListener cycleItemClilkListener) { this.cycleItemClilkListener = cycleItemClilkListener; } private CycleItemClilkListener cycleItemClilkListener; public BaseHolder(View itemView,CycleItemClilkListener listener) { super(itemView); cycleItemClilkListener = listener; itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (cycleItemClilkListener!=null){ cycleItemClilkListener.onCycleItemClick(v,getPosition()); } } }); } } public interface CycleItemClilkListener{ void onCycleItemClick(View view,int position); }
一切就绪可以试一试效果了,定义一个adapter 继承MCyclerAdapter
public class Madapter extends MCyclerAdapter<DisplayData> { @Override public int getDisplayType(int postion) { return list.get(postion).getType(); } public Madapter(List<DisplayData> list, Context context) { super(list, context); } @Override public RecyclerView.ViewHolder onCreateDisplayHolder(ViewGroup parent, int viewType) { View view = null; RecyclerView.ViewHolder holder = null; switch (viewType){ case DisplayData.TYPE_TXT: view = inflater.inflate(R.layout.item_txt,parent,false); holder = new TextHolder(view); break; case DisplayData.TYPE_IMG: view = inflater.inflate(R.layout.item_img,parent,false); holder = new ImageHolder(view); break; case DisplayData.TYPE_MULTI: break; } return holder; } @Override public void onBindData(RecyclerView.ViewHolder holder, int position) { DisplayData data = list.get(position); switch (getDisplayType(position)){ case DisplayData.TYPE_TXT: TextHolder textHolder = (TextHolder)holder; textHolder.mTxt.setText(data.getContent()); break; case DisplayData.TYPE_IMG: ImageHolder imageHolder = (ImageHolder)holder; if (data.getContent().equals("1")){ imageHolder.mImg.setImageResource(R.drawable.img001); }else{ imageHolder.mImg.setImageResource(R.drawable.img002); } break; case DisplayData.TYPE_MULTI: break; } } class TextHolder extends BaseHolder{ TextView mTxt; public TextHolder(View itemView) { super(itemView, new CycleItemClilkListener() { @Override public void onCycleItemClick(View view, int position) { Toast.makeText(context,position+"",Toast.LENGTH_SHORT).show(); } }); mTxt = (TextView)itemView.findViewById(R.id.mText); } } class ImageHolder extends RecyclerView.ViewHolder{ ImageView mImg; public ImageHolder(View itemView) { super(itemView); mImg = (ImageView)itemView.findViewById(R.id.mImg); } } }剩下的就是 new Adapter,setAdapter与listview无异
来看看效果~
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories