当前位置: 移动技术网 > 移动技术>移动开发>Android > 详解xamarin Android 实现ListView万能适配器

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网