详解xamarin Android 实现ListView万能适配器
早些时候接触xamarin Android 的列表,写了很多ListView的Adapter,建一个ListView就写一个Adapter,每一个Adapter里面还有去写一个ViewHolder的类来优化,自从看了hongyang博客的listview万能适配器的文章,学习良多,所以就写篇关于xamarin android ListView通用适配器的文章。
本章主要分为以下三点:
打造通用的ViewHolder优化ListView性能
public class ViewHolder:Java.Lang.Object { private SparseArray<View> Views; View ConvertView; private Context context ; int mPosition; private ViewHolder(Context _context,ViewGroup parent ,int itemLayoutId,int position) { this.mPosition = position; Views = new SparseArray<View>(); ConvertView = LayoutInflater.From(_context).Inflate(itemLayoutId,null); ConvertView.Tag = this; } public static ViewHolder Get(Context context , View convertView,ViewGroup parent ,int itemLayoutId,int position) { if (convertView == null) { return new ViewHolder(context, parent, itemLayoutId, position); } else { ViewHolder holder = (ViewHolder)convertView.Tag; holder.mPosition = position; return holder; } } public T GetView<T>(int viewId) where T :View { View view = Views.Get(viewId); if (view == null) { view = ConvertView.FindViewById<T>(viewId); Views.Put(viewId,view); } return (T)view; } public View GetConvertView() { return ConvertView; } /// <summary> /// 给TextView 设置文本 /// </summary> /// <param name="viewId"></param> /// <param name="text"></param> /// <returns></returns> html" target="_blank">public ViewHolder SetText(int viewId ,string text) { TextView view = GetView<TextView>(viewId); view.Text = text; return this; } /// <summary> /// 给ImageView 设置图片 /// </summary> public ViewHolder SetImageBitMap(int viewId , Bitmap bm) { ImageView view = GetView<ImageView>(viewId); view.SetImageBitmap(bm); return this; } }
稍微解释一下:
ViewHolder的构造方法中初始化变量,并将ListView的布局view的Tag设置成viewholder的实例
Get方法使用单例模式初始化ViewHolder
GetView泛型方法获取ListView布局中的空间
SetText、SetImageBitMap给一些常用的控件复值
使用泛型Adapter适应不同布局的ListView
CommonAdapter是一个泛型的基类,一些重复的重写方法都在这个基类,然后我们写一个子类继承这个CommonAdapter,就简化了很多代码
public abstract class CommonAdapter<T> :BaseAdapter { Context mContext; List<T> mData; int mItemLayoutId; public CommonAdapter(Context context, List<T> data, int itemLayoutId):base() { this.mContext = context; mData = data; mItemLayoutId = itemLayoutId; } public override int Count { get { return mData.Count; } } public override Java.Lang.Object GetItem(int position) { return null; } public override long GetItemId(int position) { return position; } public override View GetView(int position, View convertView, ViewGroup parent) { var item = mData[position]; ViewHolder viewHolder = ViewHolder.Get(mContext, convertView, parent, mItemLayoutId, position); convert(viewHolder,mData[position]); System.Diagnostics.Debug.Write(position); return viewHolder.GetConvertView(); } public abstract void convert(ViewHolder helper, T item); public ViewHolder GetViewHolder(int position, View convertView, ViewGroup parent) { return ViewHolder.Get(mContext, convertView, parent, mItemLayoutId, position); } }
写一个newsAdapter继承CommonAdapter,只需要将赋值的代码写在重写方法convert里面极客,这样就简化了很多的代码
public class NewsAdapter<T> : CommonAdapter<T> { public NewsAdapter(Context context, List<T> data, int resId) : base(context, data, resId) { } public override void convert(ViewHolder helper, T item) { NewsViewModel model = (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代码如下:
public class Common1Adapter<T> : BaseAdapter { Context mContext; List<T> mData; int mItemLayoutId; public delegate View GetViewEvent(int position, View convertView, ViewGroup parent, T item, ViewHolder viewHolder); public event GetViewEvent OnGetView; public Common1Adapter(Context context, List<T> data, int itemLayoutId) : base() { this.mContext = context; mData = data; mItemLayoutId = itemLayoutId; } public override int Count { get { return mData.Count; } } public override Java.Lang.Object GetItem(int position) { return null; } public override long GetItemId(int position) { return position; } public override View GetView(int position, View convertView, ViewGroup parent) { var item = mData[position]; ViewHolder viewHolder = ViewHolder.Get(mContext, convertView, parent, mItemLayoutId, position); if (OnGetView != null) return this.OnGetView(position,convertView,parent,item,viewHolder); return convertView; } } }
在使用时,只需要在Activity中注册OnGetView 事件,这样多个ListView的Adapter就只需要一个通用的Adapter就行了
View OnGetView(int position,View convertView,ViewGroup parent,NewsViewModel model,ViewHolder viewHolder) { 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); return viewHolder.GetConvertView(); } List<NewsViewModel> list_news = new List<Adaptes.NewsViewModel>() { new Adaptes.NewsViewModel () { NewsID =1,Title="测试标题124578cdascdas",Desc ="测acdsdas试内内容10c2da4s内容10c2da4s内容10c2da4s容10c2da4sc5das4cdas"}, new Adaptes.NewsViewModel () { NewsID =2,Title="cascascda24578cdascdas",Desc ="测dasc试内容10c2da4s内容10c2da4s内容10c2da4s内容10c2da4sc5das4cdas"}, }; Common1Adapter<NewsViewModel> adapter = new Adaptes.Common1Adapter<Adaptes.NewsViewModel>(this, list_news, Resource.Layout.item_listview_news); adapter.OnGetView += OnGetView; lv_news.Adapter = adapter;
以上就是Android listview 万能适配器的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍MySQL适配器PyMySQL详解,包括了MySQL适配器PyMySQL详解的使用技巧和注意事项,需要的朋友参考一下 本文我们为大家介绍 Python3 使用 PyMySQL 连接数据库,并实现简单的增删改查。 什么是 PyMySQL? PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。 PyMySQL 遵循
本文向大家介绍Java适配器模式应用之电源适配器功能详解,包括了Java适配器模式应用之电源适配器功能详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java适配器模式应用之电源适配器功能。分享给大家供大家参考,具体如下: 一、模式定义 存在两种适配器模式 1 对象适配器模式,在这种适配器模式中,适配器容纳一个它包裹的类对象的物理实体。 2 类适配器模式,在这种适配器模式中,适配器继承
本文向大家介绍详解ListView中多种item的实现方式,包括了详解ListView中多种item的实现方式的使用技巧和注意事项,需要的朋友参考一下 大家都知道在实际开发时,对ListView的使用比较频繁,其表现也非常复杂。本文将通过实例介绍ListView中多种item的实现方式,下面来一起看看吧。 使用ListView一般步骤: 设置显示的ListView,设置显示的每一项item的vie
本文向大家介绍JavaScript适配器模式详解,包括了JavaScript适配器模式详解的使用技巧和注意事项,需要的朋友参考一下 适配模式可用来在现有接口和不兼容的类之间进行适配,使用这种模式的对象又叫包装器(wrapper),因为它们是在用一个新的接口包装另一个对象。 基本理论 适配器模式:将一个接口转换成客户端需要的接口而不需要去修改客户端代码,使得不兼容的代码可以一起工作。 适配器主要有3
我有一块碎片。加载的视图的onCreateView方法上的这个片段有一个ListView(a)(在适配器(a)中填充)。但是,此ListView(A)中有另一个ListView(B)。所以现在,我必须调用适配器(B)来填充这个listview(B)。如果我从片段调用它,我会得到一个空指针,如果我从适配器调用它(a),它不会崩溃,但不会工作。 如何调用另一个适配器中的适配器。 这是片段的代码: 其中
本文向大家介绍C++实现万年历功能,包括了C++实现万年历功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C++实现万年历的具体代码,供大家参考,具体内容如下 1.此万年历功能 1>日期加减天数 2>日期与日期之间的差值 3>输入年月显示当月日历 2.代码实现 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。