ViewHolder模式超简洁写法,很cool!

转自http://www.eoeandroid.com/forum.php?mod=viewthread&tid=321547&page=3#pid3555274



ViewHolder是什么就不解释了。

        大家通常怎么写ViewHolder呢?
01        ViewHolder holder =null;
02        if(convertView ==null){
03                convertView = mInflater.inflate(R.layout.xxxnull);
04                holder =new ViewHolder();
05                holder.tvXXX = (TextView)findViewById(R.id.xxx);
06                //...一连串的findViewById
07        }
08        else{
09                holder = (ViewHolder) convertView.getTag();  
10        }
11         
12         
13         
14        privatestatic class ViewHolder{
15                TextView tvXXX;
16                //很多view的定义
17        }



      这么写一次还行,但问题是总有很多很多的ViewAdapter要这么写,每次都repeat,repeat,repeat  累啊。      所以,有这么一种简洁的写法分享给大家,先声明,从国外网站上看的,不是自己原创的,但确实很喜欢这个简洁的设计。

ViewHolder这么写(只提供一个静态方法,其实可以加一个私有构造函数防止外部实例化),代码很简单,看过就明白了
01public classViewHolder {
02    // I added a generic return type to reduce the casting noise in client code
03    @SuppressWarnings("unchecked")
04    publicstatic <T extendsView> T get(View view, intid) {
05        SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
06        if(viewHolder == null) {
07            viewHolder =new SparseArray<View>();
08            view.setTag(viewHolder);
09        }
10        View childView = viewHolder.get(id);
11        if(childView == null) {
12            childView = view.findViewById(id);
13            viewHolder.put(id, childView);
14        }
15        return(T) childView;
16    }
17}



在getView里这样
01@Override
02public View getView(intposition, View convertView, ViewGroup parent) {
03 
04    if(convertView == null) {
05        convertView = LayoutInflater.from(context)
06          .inflate(R.layout.banana_phone, parent,false);
07    }
08 
09    ImageView bananaView = ViewHolder.get(convertView, R.id.banana);
10    TextView phoneView = ViewHolder.get(convertView, R.id.phone);
11 
12    BananaPhone bananaPhone = getItem(position);
13    phoneView.setText(bananaPhone.getPhone());
14    bananaView.setImageResource(bananaPhone.getBanana());
15 
16    returnconvertView;
17}



        哈哈,完成了,果断把这个ViewHolder类加入自己的utils,一劳永逸了以后~

        值得注意的是SparseArray这个知识点,优化过的存储integer和object键值对的hashmap,网上资料很多这里就不废话了~




其实这种写法本质和ViewHolder Partten没有什么不同,ViewHolder Partten是把一个自定义类绑定到一个view,这种是把SparseArray绑定到一个view,虽然SparseArray 初始化会分配10长度的地址,理论上貌似浪费了内存,理论上插入和删除操作也是有时间损耗的,但是这些都在允许范围内。

比如https://github.com/JoanZapata/base-adapter-helper 作者也说了他做了大量测试,这种损耗微乎其微。

再次,万一万一因特殊情况发现了有性能瓶颈,到时候再优化就可以了,但是绝大多数场合都是可以使用的,大量简化你的开发,加快开发速度,代码少了,出错的几率就小了,维护的成本也小了~好处还是大大的。



简单的纸上分析~:
(1)ViewHolder Pattern是每一个View一个ViewHolder,里面是记录listitem内控件引用; SparseArray是记录id和控件引用的键值对,当然SparseArray初始化会分配一定地址空间(默认是10),但是这些内存损耗应该是可以忽略的~
(2)SparseArray是优化过的int-object的hashmap,使用折半查找,并优化了内存分配,所以代码执行成本通常是可控的。

综上,使用SparseArray与ViewHolder相比是有损耗,但应该是可控的。使用SparseArray优点是加快开发速度和减少代码维护,当发现有性能瓶颈时,再进行优化~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值