详解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

标签:Android,listview
0
投稿

猜你喜欢

  • 详解C# FileStream类

    2022-10-19 13:44:27
  • Java如何实现单链表的增删改查

    2021-09-19 09:49:25
  • Java实现五子棋游戏的完整代码

    2022-07-01 15:32:34
  • Java深入讲解二十三种设计模式之中的策略模式

    2022-11-25 13:23:15
  • springboot动态调整日志级别的操作大全

    2023-11-03 19:31:12
  • SpringBoot整合jersey的示例代码

    2021-08-28 05:23:12
  • 详解Android中Activity运行时屏幕方向与显示方式

    2022-02-12 03:51:06
  • C++多重继承二义性原理实例解析

    2021-10-08 20:18:33
  • mybatis insert返回主键代码实例

    2022-04-08 02:24:01
  • c#语言程序构建基块

    2023-04-11 22:40:12
  • springboot项目以jar包运行的操作方法

    2023-11-10 07:47:43
  • AndroidUI组件SlidingTabLayout实现ViewPager页滑动效果

    2023-05-17 14:28:22
  • 详解SpringBoot 快速整合MyBatis(去XML化)

    2022-08-19 16:42:54
  • 基于IntelliJ IDEA的类注释和方法注释操作

    2023-03-04 02:00:31
  • 浅谈C# winForm 窗体闪烁的问题

    2023-06-10 09:46:07
  • springboot自动配置原理解析

    2021-06-01 17:54:33
  • CountDownLatch和Atomic原子操作类源码解析

    2023-06-07 06:31:52
  • 使用itextpdf操作pdf的实例讲解

    2022-11-16 00:22:43
  • c# 引用类型和值类型

    2023-10-11 08:20:48
  • C++智能指针实例详解

    2021-12-18 00:38:59
  • asp之家 软件编程 m.aspxhome.com