ViewHolder

做过安卓开发,基本都知道ListView,GridView等控件是使用适配器来绑定数据到视图上的,而他们都使用了视图回收来优化列表滚动,避免的频繁地创建和销毁条目(Item)视图(哈哈,这有点像异步消息处理机制中Message对象的回收哈)。

那么系统已经优化了又有我们什么事呢?原因在于当item一多,滑动时,特别是快速滑动,不断地调用适配器getView()方法,那么我们在getView里面所做的事情就严重影响到滑动的流畅程度了,比如执行一次需要一秒,那么滑动复用一条item时就会卡那里一秒,一千条。。。。。。

那么问题来了,我们在getView里面做了什么事情呢?没错不就是创建视图(或使用已回收的视图)寻找里面的子控件并绑定数据吗?如同从LinearLayout中找到一个TextView并调用setText()设置显示文本。

这个过程中,有哪些是可以优化的呢?由于每个item的显示文本可能都不一样,所以setText()这个过程是必不可少的,那么寻找子控件的过程呢?ListView每个item都有一样的一组控件,而我们每次都要从里面找到一个特定的控件来设置显示数据,这个过程我们一般都是用findViewById来实现,遍历一整组的控件(控件通常含有子控件,层层遍历)直到找到了那个特定ID的控件为止,明显这个过程是比较耗时的,而我们每次执行getView都在做着同样的遍历查找工作。

所以有了ViewHolder,查找完一次将结果(控件引用缓存起来),下次直接用,不需要再查找。
由于每个ViewHolder保存的控件引用都是对应当前条目视图的,所以将ViewHolder对象保存在视图对象中,如果视图是回收来的,他身上就有ViewHolder对象,我们直接取出就可以轻易拿到我们要的控件了

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Item currentItem = items.get(position);
            ViewHolder viewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.item_lv_headword, parent, false);
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            viewHolder.tv_headword_item_name.setText(currentItem.name);
            return convertView;
        }
static class ViewHolder {
        private TextView tv_headword_item_name;

        public ViewHolder(View convertView) {
            //因为每次创建视图只需执行一次findViewById,所以放在构造方法中
            tv_headword_item_name = (TextView) convertView.findViewById(R.id.tv_headword_item_name);
        }
    }

    static class ItemData {
        private String name;

        private ItemData(String name) {
            this.name = name;
        }
    }

这样我们就实现使用ViewHolder优化ListView的滑动(其实就是优化调用findViewById()的次数)
其实这个大家都懂,我只是想锻炼一下表述能力,但貌似还是没表达好

关于ViewHolder为何要使用静态内部类的问题:
网上有人说静态是让他无论new多少次ViewHolder都只存在一个实例,不会重新分配内存,以此达到节省内存的目的,,,

我只想说,,,略坑,面试被问到这么答除了暴露java基础不好,智商不够,没别的了

推荐使用静态内部类是因为静态内部类比普通的内部类性能高。那他们肯定有区别,不然怎么会静态的性能比较高呢?
没错的,还记得写代码时想在普通的内部类里面调用外部类方法吗?没错,直接调就行了(或者外部类类名.this.方法名)why?因为内部类默认持有了外部类的引用,(可以看成是内部类里面有个成员变量,这个成员变量是外部类的实例,当然事实不是这样的),那么这个引用就得有人为他赋值,这个赋值过程不知道是怎样的,但明显会多执行些代码,不然也不会建议使用静态内部类了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值