Android 中RecyclerView通用适配器的实现
Android中RecyclerView通用适配器的实现
前言:
SDK的5.0版本出来已经N久了,可以说是已经经过许多人的检验了,里面的新控件不能说是非常完美,但也是非常好用了,其中最让我喜爱的就是RecyclerView了,可以完美替代ListView和GridView(除了添加headerview和footview了,网上有许多解决方式。这个下面会以一种简单的方式顺带解决,肯定为大家省心),而且可以代码动态切换这两种布局方式以及瀑布流布局。相关切换方式网上有很多,大家自行搜索,我就不贴连接了。
相信大家在之前使用listview时肯定一直很厌烦重复编写无数的adapter,当然有那么一部分机智如我的人肯定一直使用着万能适配器。然而RecyclerView要求我们必须使用ViewHolder来实现adapter。这就让许多用惯了万能适配器的人不爽了。今天我就提供一直基于listview万能适配器的实现原理来改良实现的RecyclerView的通用适配器,由于不是教学,切代码比较简单,就不分段讲解了,相信大家看注释就能看懂。
一共两个类,一个是继承了系统的Android.support.v7.widget.RecyclerView.ViewHolder所实现的RViewHolder类,通过他实现任意控件的缓存一个是继承了android.support.v7.widget.RecyclerView.Adapter所实现的RBaseAdapter类。
实现代码:
RViewHolder
importandroid.content.Context; importandroid.graphics.Bitmap; importandroid.support.v7.widget.RecyclerView.ViewHolder; importandroid.util.SparseArray; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.ImageView; importandroid.widget.TextView; publicclassRViewHolderextendsViewHolder{ privateContextmContext; privateViewmConvertView; privateSparseArraymViews; publicRViewHolder(ViewitemView){ super(itemView); mConvertView=itemView; this.mViews=newSparseArray (); } publicstaticRViewHolderget(Contextcontext,ViewGroupparent,intlayoutId,intposition){ Viewview=LayoutInflater.from(context).inflate(layoutId,parent,false); returnnewRViewHolder(view); } /** *通过控件的Id获取对于的控件,如果没有则加入views * *@paramviewId *@return */ public TgetView(intviewId){ Viewview=mViews.get(viewId); if(view==null){ view=mConvertView.findViewById(viewId); mViews.put(viewId,view); } return(T)view; } /** *为TextView设置字符�? * *@paramviewId *@paramtext *@return */ publicViewHoldersetText(intviewId,Stringtext){ TextViewview=getView(viewId); view.setText(text); returnthis; } /** *为ImageView设置图片 * *@paramviewId *@paramdrawableId *@return */ publicViewHoldersetImageResource(intviewId,intdrawableId){ ImageViewview=getView(viewId); view.setImageResource(drawableId); returnthis; } /** *为ImageView设置图片 * *@paramviewId *@paramdrawableId *@return */ publicViewHoldersetImageBitmap(intviewId,Bitmapbm){ ImageViewview=getView(viewId); view.setImageBitmap(bm); returnthis; } publicViewgetConvertView(){ returnmConvertView; } }
这里是RBaseAdapter
importjava.util.ArrayList; importjava.util.Collection; importjava.util.List; importandroid.content.Context; importandroid.support.v7.widget.RecyclerView.Adapter; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.LinearLayout; publicabstractclassRBaseAdapterextendsAdapter { privateContextmContext; privateList list; protectedLayoutInflatermInflater; privateintmItemLayoutId; publicRBaseAdapter(Contextcontext){ //TODOAuto-generatedconstructorstub this.mContext=context; this.mInflater=LayoutInflater.from(mContext); this.mItemLayoutId=newLinearLayout(mContext).getId(); this.list=newArrayList (); } publicRBaseAdapter(Contextcontext,List list){ //TODOAuto-generatedconstructorstub this.mContext=context; this.mInflater=LayoutInflater.from(mContext); this.mItemLayoutId=newLinearLayout(mContext).getId(); this.list=list; } publicRBaseAdapter(Contextcontext,List list,intitemLayoutId){ this.mContext=context; this.mInflater=LayoutInflater.from(mContext); this.mItemLayoutId=itemLayoutId; this.list=list; } publicRBaseAdapter(Contextcontext,intitemLayoutId){ this.mContext=context; this.mInflater=LayoutInflater.from(mContext); this.mItemLayoutId=itemLayoutId; this.list=newArrayList (); } publicvoidsetitemLayoutId(intitemLayoutId){ this.mItemLayoutId=itemLayoutId; } publicList getList(){ returnthis.list; } publicvoidappendList(List list){ //TODOAuto-generatedmethodstub this.list=list; notifyDataSetChanged(); } publicvoidaddList(List list2){ //TODOAuto-generatedmethodstub this.list.addAll((Collection)list2); notifyDataSetChanged(); } @Override publicintgetItemCount(){ returnlist.size(); } booleanhasHeader=false; booleanhasFooter=false; ViewheaderView; ViewfooterView; publicvoidsetHeaderView(ViewheaderView){ hasHeader=true; this.headerView=headerView; } publicvoidsetFooterView(ViewfooterView){ hasFooter=true; this.footerView=footerView; } publicViewgetHeaderView(){ returnheaderView; } publicViewgetFooterView(){ returnfooterView; } @Override publicvoidonBindViewHolder(RViewHolderholder,intposition){ if(hasHeader&&position==0){ return; }elseif(hasFooter&&position==(list.size()+(hasHeader?1:0))){ return; }else convert(holder,(T)list.get(position)); } @Override publicRViewHolderonCreateViewHolder(ViewGroupparent,intposition){ if(hasHeader&&position==0){ returnnewRViewHolder(headerView); }elseif(hasFooter&&position==(list.size()+(hasHeader?1:0))){ returnnewRViewHolder(footerView); }else returnRViewHolder.get(mContext,parent,mItemLayoutId,position); } //这里定义抽象方法,我们在匿名内部类实现的时候实现此方法来调用控件 publicabstractvoidconvert(RViewHolderholder,Titem); }
对于RBaseAdapter稍微讲解下,首先是泛型,这样任何对象类型都可以使用,再来就是前面提到的headerview和footerview的解决,可以看到RBaseAdapter里面定义了几个方法,通过position的不同来加载不同的布局的思想来添加headerview和footerview。
Activity里面调用
recyclerView.setAdapter(newRBaseAdapter(mContext,R.layout.virtual_win_users_list_item){ @Override publicvoidconvert(RViewHolderholder,VirtualWinsBeanitem){ if(Util.checkNULL(item.getNick_name())){ holder.setText(R.id.name,Util.HidePhone(item.getPhone()+"")); }else{ holder.setText(R.id.name,item.getNick_name()); } RoundImageViewnetworkImageView=holder.getView(R.id.photo); networkImageView.setLoadingImage(R.drawable.header_def); networkImageView.setDefultImage(R.drawable.header_def); networkImageView.LoadUrl(U.g(item.getFile_url())); } });
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!