详解xamarin Android 实现ListView万能适配器
详解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;
以上就是Android listview 万能适配器的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
- 怎样提高网站访问速度缩短网页加载时间
- 使用Kotlin开发一个Spring Boot Webflux Streaming应用(附视频)
- 插入排序算法
- Javascript 的addEventListener()及attachEvent()区别分析
- 设计模式-用接口来实现filter!梭梭就是干!
- OpenDaylight实现轮询策略的负载均衡服务
- 微服务业务开发三个难题-拆分、事务、查询(上)
- 总结了一些指针易出错的常见问题(五)
- 微服务业务开发三个难题-拆分、事务、查询(下)
- C语言之控制台读取上下左右方向键指令
- C程序之修改Windows的控制台大小
- VS2010/MFC编程(对话框:模态对话框及其弹出过程)
- 设计模式-抽象类,只是想为你做更多
- 设计模式-搞个接口,留有余地,让你我不再尴尬
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Flutter适配深色模式的方法(DarkMode)
- RecyclerView+SnapHelper实现无限循环筛选控件
- 详解Android 8.1.0 Service 中 弹出 Dialog的方法
- 短信收发类无错版JustinIO.cs
- Android快速实现无预览拍照功能
- RecyclerView+PagerSnapHelper实现抖音首页翻页的Viewpager效果
- android中使用react-native设置应用启动页过程详解
- 面试官问我单例模式真的安全吗?我懵逼了
- 详解Android使用CoordinatorLayout+AppBarLayout实现拉伸顶部图片功能
- Android自定义控制条效果
- Android使用MediaPlayer和TextureView实现视频无缝切换
- Android实现静默拍照功能
- Android实现动态体温计
- Android实现倾斜角标样式
- 浅谈Flutter 中渐变的高级用法(3种)