欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-12 17:48:22
详解xamarin android 实现listview万能适配器 早些时候接触xamarin android 的列表,写了很多listview的adapter,建一个l...

详解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 万能适配器的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

上一篇:

下一篇: