详解xamarin Android 实现ListView万能适配器
详解xamarinAndroid实现ListView万能适配器
早些时候接触xamarinAndroid的列表,写了很多ListView的Adapter,建一个ListView就写一个Adapter,每一个Adapter里面还有去写一个ViewHolder的类来优化,自从看了hongyang博客的listview万能适配器的文章,学习良多,所以就写篇关于xamarinandroidListView通用适配器的文章。
本章主要分为以下三点:
- 打造通用的ViewHolder优化ListView性能
- 使用泛型Adapter适应不同布局的ListView
- C#委托和Java匿名内部类的比较
打造通用的ViewHolder优化ListView性能
publicclassViewHolder:Java.Lang.Object { privateSparseArrayViews; ViewConvertView; privateContextcontext; intmPosition; privateViewHolder(Context_context,ViewGroupparent,intitemLayoutId,intposition) { this.mPosition=position; Views=newSparseArray (); ConvertView=LayoutInflater.From(_context).Inflate(itemLayoutId,null); ConvertView.Tag=this; } publicstaticViewHolderGet(Contextcontext,ViewconvertView,ViewGroupparent,intitemLayoutId,intposition) { if(convertView==null) { returnnewViewHolder(context,parent,itemLayoutId,position); } else { ViewHolderholder=(ViewHolder)convertView.Tag; holder.mPosition=position; returnholder; } } publicTGetView (intviewId)whereT:View { Viewview=Views.Get(viewId); if(view==null) { view=ConvertView.FindViewById (viewId); Views.Put(viewId,view); } return(T)view; } publicViewGetConvertView() { returnConvertView; } /// ///给TextView设置文本 /// ////// /// publicViewHolderSetText(intviewId,stringtext) { TextViewview=GetView (viewId); view.Text=text; returnthis; } /// ///给ImageView设置图片 /// publicViewHolderSetImageBitMap(intviewId,Bitmapbm) { ImageViewview=GetView(viewId); view.SetImageBitmap(bm); returnthis; } }
稍微解释一下:
ViewHolder的构造方法中初始化变量,并将ListView的布局view的Tag设置成viewholder的实例
Get方法使用单例模式初始化ViewHolder
GetView泛型方法获取ListView布局中的空间
SetText、SetImageBitMap给一些常用的控件复值
使用泛型Adapter适应不同布局的ListView
CommonAdapter是一个泛型的基类,一些重复的重写方法都在这个基类,然后我们写一个子类继承这个CommonAdapter,就简化了很多代码
publicabstractclassCommonAdapter:BaseAdapter { ContextmContext; List mData; intmItemLayoutId; publicCommonAdapter(Contextcontext,List data,intitemLayoutId):base() { this.mContext=context; mData=data; mItemLayoutId=itemLayoutId; } publicoverrideintCount { get { returnmData.Count; } } publicoverrideJava.Lang.ObjectGetItem(intposition) { returnnull; } publicoverridelongGetItemId(intposition) { returnposition; } publicoverrideViewGetView(intposition,ViewconvertView,ViewGroupparent) { varitem=mData[position]; ViewHolderviewHolder=ViewHolder.Get(mContext,convertView,parent,mItemLayoutId,position); convert(viewHolder,mData[position]); System.Diagnostics.Debug.Write(position); returnviewHolder.GetConvertView(); } publicabstractvoidconvert(ViewHolderhelper,Titem); publicViewHolderGetViewHolder(intposition,ViewconvertView,ViewGroupparent) { returnViewHolder.Get(mContext,convertView,parent,mItemLayoutId,position); } }
写一个newsAdapter继承CommonAdapter,只需要将赋值的代码写在重写方法convert里面极客,这样就简化了很多的代码
publicclassNewsAdapter:CommonAdapter { publicNewsAdapter(Contextcontext,List data,intresId):base(context,data,resId) { } publicoverridevoidconvert(ViewHolderhelper,Titem) { NewsViewModelmodel=(NewsViewModel)Convert.ChangeType(item,typeof(NewsViewModel)); helper.SetText(Resource.Id.tv_news_title,model.Title); helper.SetText(Resource.Id.tv_news_id,model.NewsID.ToString()); helper.SetText(Resource.Id.tv_news_desc,model.Desc); } }
C#委托和Java匿名内部类的比较
看来上面的例子,虽然简化了很多代码,但是每个ListView还是得新建一个Adapter,看来hongyang大神的博客在java中用匿名内部类实现一个Adapter万能通用,但是c#中没有匿名内部内的概念,这就尴尬了。。。。。
c#中虽然没有这种概念,但语言是相通的,但是委托可以实现。万能通用的adapter代码如下:
publicclassCommon1Adapter:BaseAdapter { ContextmContext; List mData; intmItemLayoutId; publicdelegateViewGetViewEvent(intposition,ViewconvertView,ViewGroupparent,Titem,ViewHolderviewHolder); publiceventGetViewEventOnGetView; publicCommon1Adapter(Contextcontext,List data,intitemLayoutId):base() { this.mContext=context; mData=data; mItemLayoutId=itemLayoutId; } publicoverrideintCount { get { returnmData.Count; } } publicoverrideJava.Lang.ObjectGetItem(intposition) { returnnull; } publicoverridelongGetItemId(intposition) { returnposition; } publicoverrideViewGetView(intposition,ViewconvertView,ViewGroupparent) { varitem=mData[position]; ViewHolderviewHolder=ViewHolder.Get(mContext,convertView,parent,mItemLayoutId,position); if(OnGetView!=null) returnthis.OnGetView(position,convertView,parent,item,viewHolder); returnconvertView; } } }
在使用时,只需要在Activity中注册OnGetView事件,这样多个ListView的Adapter就只需要一个通用的Adapter就行了
ViewOnGetView(intposition,ViewconvertView,ViewGroupparent,NewsViewModelmodel,ViewHolderviewHolder) { viewHolder.SetText(Resource.Id.tv_news_title,model.Title); viewHolder.SetText(Resource.Id.tv_news_id,model.NewsID.ToString()); viewHolder.SetText(Resource.Id.tv_news_desc,model.Desc); returnviewHolder.GetConvertView(); } Listlist_news=newList (){ newAdaptes.NewsViewModel(){NewsID=1,Title="测试标题124578cdascdas",Desc="测acdsdas试内内容10c2da4s内容10c2da4s内容10c2da4s容10c2da4sc5das4cdas"}, newAdaptes.NewsViewModel(){NewsID=2,Title="cascascda24578cdascdas",Desc="测dasc试内容10c2da4s内容10c2da4s内容10c2da4s内容10c2da4sc5das4cdas"}, }; Common1Adapter adapter=newAdaptes.Common1Adapter (this,list_news,Resource.Layout.item_listview_news); adapter.OnGetView+=OnGetView; lv_news.Adapter=adapter;
以上就是Androidlistview万能适配器的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!