【译文】高性能ListViews

原文链接 : Performance ListViews
原文作者 : Brandon
译文出自 : 开发技术前线 www.devtf.cn。未经允许,不得转载!
译者 : liuling07
校对者: desmond1121
状态 : 完成

译文连接:高性能ListViews


表展示功能几乎在所有app中都会被用到,使用列表可以很方便的展示一些列表项,比如菜谱、联系人,或者任意类型的类别。所以Android有一个内置的
方式来展示此类型的数据,也是在情理之中的。RecyclerView是一种最新的展示列表数据的方式,它非常高效,因为它重用视图而不是每一行出现在屏
幕上都重新创建。在RecyclerView出现之前,我们可以使用ListView,即使到了现在,ListView也是广泛的被开发者所使用。虽然
ListView也是可以回收视图的,但它也一直都是Android中最容易被错误使用的一个控件。我们知道在此之前这个话题已经被写过无数遍了,但是今
天我还是要在博客中提出来,因为我们仍然发现很多app在错误的使用它们。

关于ListView中ArrayAdapter的用法,标准的新手写法是这样子的:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.view_test_row, parent, false);

    TextView testName = (TextView)rowView.findViewById(R.id.text_view_test_name);
    TextView testDesc = (TextView)rowView.findViewById(R.id.text_view_test_desc);

    //modify TextViews, in some arbitrary way

    return rowView;
}

当所有列表项都能够一次性在一屏中显示的时候,这种写法并没有什么问题,但这样你就创建了一个基本视图,并完全避免了ArrayAdapter的麻
烦了吗?当ListView需要显示一个很大的列表集,而且列表子项是一个非常复杂的视图的时候,上面的方式会消耗大量的性能。当用户滑动屏幕的时候,每
个视图都会被inflate并且调用findViewById()方法。当findViewById()方法被调用的时候,会遍历整个视图层级,直到找到
正确的Id。每个子视图都要执行上述过程!并且用户滑动的越快,卡顿现象愈加明显。为了解决这个问题,我们可以使用一个静态类来绑定还没被使用的
convertView。

static class ViewHolder(){

        TextView testName;
        TextView testDesc;

}

@Override
 public View getView(int position, View convertView, ViewGroup parent) {

    View rowView = convertView;  //reference to one of the previous Views in the list that we can reuse.

    if(convertView == null) {

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.view_test_row, parent, false);

        ViewHolder viewHolder = new ViewHolder();
        viewHolder.testName = (TextView) rowView.findViewById(R.id.text_view_test_name);
        viewHolder.testDesc = (TextView) rowView.findViewById(R.id.text_view_test_desc);

        rowView.setTag(viewHolder);
    }

    ViewHolder holder = (ViewHolder) rowView.getTag();

    //in real code these strings should be in res
    holder.testName.setText("Test"+position);
    holder.testDesc.setText("This is number "+position);

    return rowView;
}

那convertView又是什么呢?它可以让ListView跳过一些显示一行内容所需要的设置。如果某一行的视图不在屏幕中显示,我们可以重复
使用这个视图来显示一个新行。当ListView刚开始显示的时候,一切都是正常的。既然没有视图可以被用来复用,convertView为空。视图也像
前面版本一样被inflate,但是TextViews会被找到且它的引用被保存在一个ViewHolder中。然后我们可以调用setTag()方法将
ViewHolder存储在视图中。正如修订过后的getView()方法中后半段代码所示,我们可以在视图中存储后面我们需要用到的数据。

我们所做的更改可能看起来并没有太大的效果,但是随着布局越来越复杂并且数量也越来越多,效果将变得越来越明显。作为开发者,我最不想做的事就是开
发一个用户体验很差的app。所以请记住,仅仅一个低水平的ListView都有可能让一个app死掉,我们一定得避免这种情况发生。

时间: 2024-10-30 16:42:12

【译文】高性能ListViews的相关文章

七大设计准则:打造高性能的移动用户体验

在新家一点点安顿了下来,不过心里还是缺乏踏实的方向感;猫猫们也都有些瞻前顾后草木皆兵的样子,有待继续习惯;希望大家都好好的.话说眼前的这篇候选文章貌似已然有同行做过译文,不过正像 "关于BeForWeb"中所说的,我只挑那些我喜欢的 .对我自己有学习和收藏价值的内容来做译文,其他方面的因素和我没有半毛钱的关系.不多说,直接进入正题. 在人际关系中,良好的第一印象是非常重要的,人们愿意在彼此身上寻求信任与诚实,并期望在接下来的经历中重现和增强这些好感.同样的道理也体现在移动应用或互联网产

译文---C#堆VS栈(Part One)

原文:译文---C#堆VS栈(Part One) 前言 本文主要是讲解C#语言在内存中堆.栈的使用情况,使读者能更好的理解值类型.引用类型以及线程栈.托管堆.       首先感谢原文作者:Matthew Cochran 为我们带来了一篇非常好的文章,并配以大量图示,帮助我们更好的理解堆栈之间的调用,本文是在作者原文的基础上进行内容上的精简以及加入我个人在这方面的理解和注释.       最后要感谢博客园的田志良,当我搜索堆栈内部使用时,搜索到了作者的文章,吸取了大量有用的知识,而且翻译的也非常

优秀开源项目之三:高性能、高并发、高扩展性和可读性的网络服务器架构State Threads

译文在后面. State Threads for Internet Applications Introduction State Threads is an application library which provides a foundation for writing fast and highly scalable Internet Applications on UNIX-like platforms. It combines the simplicity of the multi

[译] 高性能 React:3 个新工具加速你的应用

本文讲的是[译] 高性能 React:3 个新工具加速你的应用, 原文地址:High Performance React: 3 New Tools to Speed Up Your Apps 原文作者:Ben Edelstein 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:sunui 校对者:yzgyyang.reid3290 通常来说 React 是相当快的,但开发者也很容易犯一些错误导致出现性能问题.组件挂载过慢.组件树过深和一些非必要的渲染周

并发框架Disruptor译文

Martin Fowler在自己网站上写了一篇LMAX架构的 文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JVM平台上,其核心是一个业务逻辑处理 器,它能够在一个线程里每秒处理6百万订单.业务逻辑处理器完全是运行在内存中,使用事件源驱动方式.业务逻辑处理器的核心是Disruptor. Disruptor它是一个开源的并发框架,并获得2011 Duke's 程序框架创新奖,能够在无锁的情况下实现网络的Queue并发操作.本文是Disru

[译] Swift 上的高性能数组

本文讲的是Swift 上的高性能数组, 原文地址:On Performant Arrays in Swift 原文作者:JORDAN SMITH 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:jingzhilehuakai 校对者:RickeyBoy cbangchen Swift 上的高性能数组 对于日常应用开发,考虑数组性能是一件不会经常发生的事.如果你正在实现需要扩展的算法,也许高性能数组就能出现在你脑海中.也许你正在写更偏向于底层的代码,比如

高性能计算技术也能助推大规模深度学习(百度实践)

更多深度文章,请关注:https://yq.aliyun.com/cloud 作者简介: Tiffany Trader,毕业于圣地亚哥州立大学和加州州立大学,长期致力于高性能计算.云计算.绿色计算新闻报道和分析,2015年开始担任全球知名高性能计算新闻网站HPCwire的总编辑.Tiffany Trader 的LinkedIn主页,Twitter主页.     来自百度硅谷人工智能实验室(SVAIL)的研究人员改进了众所周知的HPC通信技术,提升了通信速度,并且扩大了他们的神经网络训练规模,今天

编写高性能JavaScript(译)_javascript技巧

译者按:本人第一次翻译外文,言语难免有些晦涩,但尽量表达了作者的原意,未经过多的润色,欢迎批评指正.另本文篇幅较长.信息量大,可能难以消化,欢迎留言探讨细节问题.本文主要关注V8的性能优化,部分内容并不适用于所有JS引擎.最后,转载请注明出处: ) ========================译文分割线=========================== 很多JavaScript引擎,如Google的V8引擎(被Chrome和Node所用),是专门为需要快速执行的大型JavaScript应

怎样打造高性能的移动用户体验

在新家一点点安顿了下来,不过心里还是缺乏踏实的方向感:猫猫们也都有些瞻前顾后草木皆兵的样子,有待继续习惯:希望大家都好好的.话说眼前的这篇候选文章貌似已然有同行做过译文,不过正像 "关于BeForWeb"中所说的,我只挑那些我喜欢的 .对我自己有学习和收藏价值的内容来做译文,其他方面的因素和我没有半毛钱的关系.不多说,直接进入正题. 在人际关系中,良好的第一印象是非常重要的,人们愿意在彼此身上寻求信任与诚实,并期望在接下来的经历中重现和增强这些好感.同样的道理也体现在移动应用或互联网产