详解xamarin Android 实现ListView万能适配器
作者:张林csdn 发布时间:2022-11-26 02:12:33
详解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<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;
来源:http://blog.csdn.net/kebi007/article/details/77101947


猜你喜欢
- 前言本篇我们就来讲讲Fragment管理中的 Add() 方法Add()在我们动态的添加、管理Fragment中,Add属于最基础的方法了;
- Android XML設置屏幕方向(android:screenOrientation)详解注意:Android只支持270度旋
- 摘要:其实两种方法归结起来看还是一种,都是利用Thread的构造器进行创建,区别就是一种是无参的,一种是有参的。一、继承Thread线程类:
- 向上转型:子类对象转为父类,父类可以是接口。公式:Father f = new Son();Father是父类或接口,son是子类。向下转型
- 目录位运算按位“与” &按位“或” |异或 ^移位运算左移 <<右移 >>无符号右移 >>>
- 本文实例讲述了Android编程实现wifi扫描及连接的方法。分享给大家供大家参考,具体如下:主界面,搜索附近WIFI信息/** * Sea
- 还是有一些小问题....懒得改了,但大体思路还是清晰的,首先定义一个运算符栈,一个数栈。关于优先级,两个括号(,)优先级最低,其次是+、-,
- 2017年一直以来在公司负责爬虫项目相关工程,主要业务有预定、库存、在开发中也遇到很多问题,随手记录一下,后续会持续更新。chrome、fi
- 数学原理:  
- 目录一、二叉树的顺序存储1.堆的存储方式2.下标关系二、堆(heap)1.概念2.大/小 根堆2.1小根堆2.2大根堆3.建堆操作3.1向下
- springboot-dubbo cannot be cast to使用spring boot 集成dubbo的时候遇到问题:2018-05
- 你是否受够了每次修改静态文件都要重启服务器?有时候在一些公司前后端的职责没有那么的明确,往往后台人员也要去写一些页面,像jsp页面,或者其他
- 需求分析文档可以和项目一起进行版本管理文档可以在线访问文档可以与springboot项目集成,不需要分开部署MarkDown支持文档跟随,打
- 1.异步委托开启线程public class Program { public static void
- 本文实例讲述了C#后台创建控件并获取值的方法。分享给大家供大家参考。具体实现方法如下:前台代码:<form id="form
- 目录重入锁1. 实现重进入2. 公平与非公平获取锁的区别读写锁1. 接口示例2. 读写状态的设计3. 写锁的获取与释放4. 读锁的获取与释放
- import java.lang.reflect.InvocationHandler;import java.lang.reflect.Me
- 近期遇到了DateTime到底是值类型还是引用类型的疑惑,顺势较深入地了解一下DateTime相关的内容结论:DateTime是值类型,因为
- 这篇文章主要介绍了Java自定义实现equals()方法过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 说到人脸检测,首先要了解Haar特征分类器。Haar特征分类器说白了就是一个个的xml文件,不同的xml里面描述人体各个部位的特征值,比如人