隐藏

xamarin android tv,详解xamarin Android 实现ListView万能适配器

发布:2021/10/14 17:04:09作者:管理员 来源:本站 浏览次数:1118

详解xamarin Android 实现ListView万能适配器

早些时候接触xamarin Android 的列表,写了很多ListView的Adapter,建一个ListView就写一个Adapter,每一个Adapter里面还有去写一个ViewHolder的类来优化,自从看了hongyang博客的listview万能适配器的文章,学习良多,所以就写篇关于xamarin android ListView通用适配器的文章。

本章主要分为以下三点:

打造通用的ViewHolder优化ListView性能

使用泛型Adapter适应不同布局的ListView

C#委托和Java匿名内部类的比较

打造通用的ViewHolder优化ListView性能

public class ViewHolder:Java.Lang.Object

{

private SparseArray Views;

View ConvertView;

private Context context ;

int mPosition;

private ViewHolder(Context _context,ViewGroup parent ,int itemLayoutId,int position)

{

this.mPosition = position;

Views = new SparseArray();

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(int viewId) where T :View

{

View view = Views.Get(viewId);

if (view == null)

{

view = ConvertView.FindViewById(viewId);

Views.Put(viewId,view);

}

return (T)view;

}

public View GetConvertView()

{

return ConvertView;

}

///

/// 给TextView 设置文本

///

///

///

///

public ViewHolder SetText(int viewId ,string text)

{

TextView view = GetView(viewId);

view.Text = text;

return this;

}

///

/// 给ImageView 设置图片

///

public ViewHolder SetImageBitMap(int viewId , Bitmap bm)

{

ImageView view = GetView(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 :BaseAdapter

{

Context mContext;

List mData;

int mItemLayoutId;

public CommonAdapter(Context context, List 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 : CommonAdapter

{

public NewsAdapter(Context context, List 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 : BaseAdapter

{

Context mContext;

List 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 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 list_news = new List() {

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 adapter = new Adaptes.Common1Adapter(this, list_news, Resource.Layout.item_listview_news);

adapter.OnGetView += OnGetView;

lv_news.Adapter = adapter;

以上就是Android listview 万能适配器的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!