詳解xamarin Android 實(shí)現(xiàn)ListView萬(wàn)能適配器
詳解xamarin Android 實(shí)現(xiàn)ListView萬(wàn)能適配器
早些時(shí)候接觸xamarin Android 的列表,寫(xiě)了很多ListView的Adapter,建一個(gè)ListView就寫(xiě)一個(gè)Adapter,每一個(gè)Adapter里面還有去寫(xiě)一個(gè)ViewHolder的類(lèi)來(lái)優(yōu)化,自從看了hongyang博客的listview萬(wàn)能適配器的文章,學(xué)習(xí)良多,所以就寫(xiě)篇關(guān)于xamarin android ListView通用適配器的文章。
本章主要分為以下三點(diǎn):
- 打造通用的ViewHolder優(yōu)化ListView性能
- 使用泛型Adapter適應(yīng)不同布局的ListView
- C#委托和Java匿名內(nèi)部類(lèi)的比較
打造通用的ViewHolder優(yōu)化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 設(shè)置文本 /// </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 設(shè)置圖片 /// </summary> public ViewHolder SetImageBitMap(int viewId , Bitmap bm) { ImageView view = GetView<ImageView>(viewId); view.SetImageBitmap(bm); return this; } }
稍微解釋一下:
ViewHolder的構(gòu)造方法中初始化變量,并將ListView的布局view的Tag設(shè)置成viewholder的實(shí)例
Get方法使用單例模式初始化ViewHolder
GetView泛型方法獲取ListView布局中的空間
SetText、SetImageBitMap給一些常用的控件復(fù)值
使用泛型Adapter適應(yīng)不同布局的ListView
CommonAdapter是一個(gè)泛型的基類(lèi),一些重復(fù)的重寫(xiě)方法都在這個(gè)基類(lèi),然后我們寫(xiě)一個(gè)子類(lèi)繼承這個(gè)CommonAdapter,就簡(jiǎn)化了很多代碼
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); } }
寫(xiě)一個(gè)newsAdapter繼承CommonAdapter,只需要將賦值的代碼寫(xiě)在重寫(xiě)方法convert里面極客,這樣就簡(jiǎn)化了很多的代碼
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匿名內(nèi)部類(lèi)的比較
看來(lái)上面的例子,雖然簡(jiǎn)化了很多代碼,但是每個(gè)ListView還是得新建一個(gè)Adapter,看來(lái)hongyang大神的博客在java中用匿名內(nèi)部類(lèi)實(shí)現(xiàn)一個(gè)Adapter萬(wàn)能通用,但是c#中沒(méi)有匿名內(nèi)部?jī)?nèi)的概念,這就尷尬了。。。。。
c#中雖然沒(méi)有這種概念,但語(yǔ)言是相通的,但是委托可以實(shí)現(xiàn)。萬(wàn)能通用的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; } } }
在使用時(shí),只需要在Activity中注冊(cè)O(shè)nGetView 事件,這樣多個(gè)ListView的Adapter就只需要一個(gè)通用的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="測(cè)試標(biāo)題124578cdascdas",Desc ="測(cè)acdsdas試內(nèi)內(nèi)容10c2da4s內(nèi)容10c2da4s內(nèi)容10c2da4s容10c2da4sc5das4cdas"}, new Adaptes.NewsViewModel () { NewsID =2,Title="cascascda24578cdascdas",Desc ="測(cè)dasc試內(nèi)容10c2da4s內(nèi)容10c2da4s內(nèi)容10c2da4s內(nèi)容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 萬(wàn)能適配器的實(shí)例,如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android實(shí)現(xiàn)Tab布局的4種方式(Fragment+TabPageIndicator+ViewPager)
Android現(xiàn)在實(shí)現(xiàn)Tab類(lèi)型的界面方式越來(lái)越多,本文詳細(xì)介紹了Android實(shí)現(xiàn)Tab布局的4種方式,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-11-11Android Studio 合并module到統(tǒng)一文件夾的方法
這篇文章主要介紹了Android Studio 合并module到統(tǒng)一文件夾的方法,補(bǔ)充介紹了android studio關(guān)于同名資源文件的合并技巧,需要的朋友可以參考下2018-04-04okhttp3.4.1+retrofit2.1.0實(shí)現(xiàn)離線緩存的示例
本篇文章主要介紹了okhttp3.4.1+retrofit2.1.0實(shí)現(xiàn)離線緩存的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android連接MySQL數(shù)據(jù)庫(kù)實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Android連接MySQL數(shù)據(jù)庫(kù)實(shí)現(xiàn)方法,在Android應(yīng)用程序中連接MySQL數(shù)據(jù)庫(kù)可以幫助開(kāi)發(fā)人員實(shí)現(xiàn)更豐富的數(shù)據(jù)管理功能,而且在Android中操作數(shù)據(jù)庫(kù)真的太智能了,需要的朋友可以參考下2024-02-02Android條紋進(jìn)度條的實(shí)現(xiàn)(調(diào)整view寬度仿進(jìn)度條)
這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)條紋進(jìn)度條的方法,主要是通過(guò)調(diào)整view寬度仿進(jìn)度條,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧2018-09-09Android中Splash應(yīng)用啟動(dòng)白屏問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了Android中Splash應(yīng)用啟動(dòng)白屏問(wèn)題的兩種解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android客戶端實(shí)現(xiàn)注冊(cè)、登錄詳解(1)
這篇文章主要為大家詳細(xì)介紹了Android客戶端實(shí)現(xiàn)注冊(cè)、登錄代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android 自定義組件成JAR包的實(shí)現(xiàn)方法
這篇文章主要介紹了Android 自定義組件成JAR包的實(shí)現(xiàn)方法的相關(guān)資料,偶爾會(huì)用到這樣的功能,如果你自己自定義的組件很好,需要的朋友可以參考下2016-11-11Android仿微信對(duì)話列表滑動(dòng)刪除效果
這篇文章主要為大家詳細(xì)介紹了Android仿微信對(duì)話列表滑動(dòng)刪除效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08