您好,登錄后才能下訂單哦!
小編給大家分享一下xamarin Android如何實現ListView萬能適配器,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
本章主要分為以下三點:
打造通用的ViewHolder優化ListView性能
使用泛型Adapter適應不同布局的ListView
C#委托和Java匿名內部類的比較
打造通用的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> 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;
以上是“xamarin Android如何實現ListView萬能適配器”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。