首页技术教程极客学院eoe

eoe 移动开发者论坛

 找回密码
 加入eoe

QQ登录

只需一步,快速开始

查看: 52324|回复: 261
打印 上一主题 下一主题
收起左侧

[Android分享] ViewHolder模式超简洁写法,很cool!

  [复制链接]

9

主题

164

帖子

1343

e币
跳转到指定楼层
楼主
发表于 2014-1-14 19:15:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

没有eoe的账号,级别还太低,出门如何吹牛逼?

您需要 登录 才可以下载或查看,没有帐号?加入eoe

x
本帖最后由 zhugogogo 于 2014-6-4 13:38 编辑

        ViewHolder是什么就不解释了。
        大家通常怎么写ViewHolder呢?
[mw_shl_code=java,true]        ViewHolder holder = null;
        if(convertView == null){
                convertView = mInflater.inflate(R.layout.xxx null);
                holder = new ViewHolder();
                holder.tvXXX = (TextView)findViewById(R.id.xxx);
                //...一连串的findViewById
        }
        else{
                holder = (ViewHolder) convertView.getTag();  
        }
        
        
        
        private static class ViewHolder{
                TextView tvXXX;
                //很多view的定义
        }[/mw_shl_code]


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

ViewHolder这么写(只提供一个静态方法,其实可以加一个私有构造函数防止外部实例化),代码很简单,看过就明白了
[mw_shl_code=java,true]public class ViewHolder {
    // I added a generic return type to reduce the casting noise in client code
    @SuppressWarnings("unchecked")
    public static <T extends View> T get(View view, int id) {
        SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
        if (viewHolder == null) {
            viewHolder = new SparseArray<View>();
            view.setTag(viewHolder);
        }
        View childView = viewHolder.get(id);
        if (childView == null) {
            childView = view.findViewById(id);
            viewHolder.put(id, childView);
        }
        return (T) childView;
    }
}[/mw_shl_code]


在getView里这样
[mw_shl_code=java,true]@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = LayoutInflater.from(context)
          .inflate(R.layout.banana_phone, parent, false);
    }

    ImageView bananaView = ViewHolder.get(convertView, R.id.banana);
    TextView phoneView = ViewHolder.get(convertView, R.id.phone);

    BananaPhone bananaPhone = getItem(position);
    phoneView.setText(bananaPhone.getPhone());
    bananaView.setImageResource(bananaPhone.getBanana());

    return convertView;
}[/mw_shl_code]


        哈哈,完成了,果断把这个ViewHolder类加入自己的utils,一劳永逸了以后~
        值得注意的是SparseArray这个知识点,优化过的存储integer和object键值对的hashmap,网上资料很多这里就不废话了~

扑火つ飞蛾 分享了一个github上的开源项目小工具,更cool更简洁! 核心同样是使用SparseArray存储id+view,但更巧妙的是使用Builder模式进一步封装了常用的控件方法,进一步简化了代码~
地址是  https://github.com/JoanZapata/base-adapter-helper
大家可以去下载代码看看,更cool了,感谢扑火つ飞蛾的分享~



评分

参与人数 9e币 +323 收起 理由
ggoyea + 10 非常精彩,支持你,加油!
xjxuvup + 100 支持你发表经验帖
du_mppds + 10 吊炸天
longdawei1988 + 10
LeoElva + 50 精彩好文,必须推荐!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏316
推荐
发表于 2014-1-14 19:55:08 | 只看该作者
最简洁的写法是不写ViewHolder  使用SimpleAdapter或者SimpleCursorAdapter  重写 bindView

9

主题

164

帖子

1343

e币
推荐
 楼主| 发表于 2014-1-17 16:41:34 | 只看该作者
jj369712957 发表于 2014-1-17 15:30
楼主解释一下,会不会造成内存泄露。。。。。那样的话就没有意思了。。。。 ...

泄露?memory leak? 不会啊,你说的可能是oom, out of memory吧?

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

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

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

https://github.com/JoanZapata/base-adapter-helper 这个项目在我正文贴出的代码基础上进一步封装了许多实用的功能,更cool哦~ 可以下载好好研究一下~

9

主题

164

帖子

1343

e币
推荐
 楼主| 发表于 2014-1-15 19:11:50 | 只看该作者
newmandirl 发表于 2014-1-15 15:50
引用:
1、引入了SparseArray,那样的话,列表每一项都多了一个SparseArray,这种集合类型内部成员变量都很 ...

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

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

0

主题

272

帖子

821

e币
5
发表于 2014-1-14 19:32:07 | 只看该作者
支持一下。。。

1

主题

131

帖子

265

e币
6
发表于 2014-1-14 20:08:15 | 只看该作者
还可以这样写

14

主题

418

帖子

1087

e币
7
发表于 2014-1-14 20:25:47 | 只看该作者

0

主题

17

帖子

26

e币
8
发表于 2014-1-14 20:38:40 | 只看该作者
原来可以如此简单
9
发表于 2014-1-14 20:41:36 | 只看该作者
很有用,学习了~
10
发表于 2014-1-14 20:51:55 | 只看该作者
非常好,支持一下
11
发表于 2014-1-14 20:58:51 | 只看该作者
不错不错
12
发表于 2014-1-14 20:59:20 | 只看该作者
保存成工具类 代码看起来简洁了
13
发表于 2014-1-14 21:48:21 | 只看该作者
威武呀,果然很简洁,赞100个

3

主题

105

帖子

2181

e币
QQ认证
14
发表于 2014-1-15 08:23:21 | 只看该作者
很好,以前很多adapter都要重新写ViewHolder,唉。。。这个不错!!!
15
发表于 2014-1-15 08:30:12 | 只看该作者
真好,减少了代码量
16
发表于 2014-1-15 09:28:37 | 只看该作者
看起来真的很cool,可以减少代码量,收藏一下,以后用。。。
17
发表于 2014-1-15 10:06:31 | 只看该作者
挺好的  收藏了
您需要登录后才可以回帖 登录 | 加入eoe

本版积分规则

推荐阅读
赞助商们

QQ|新帖|小黑屋|eoe 移动开发者论坛 ( 京ICP备11018032 京公网安11010802020210  

GMT+8, 2018-10-16 07:28 , Processed in 0.215615 second(s), 41 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表