zoukankan      html  css  js  c++  java
  • 转:ListView中getView的工作原理

    ListView中getView的工作原理:

    [1]ListView asks adapter “give me a view” (getView) for each item of the list.(通过getView来获取每个item)

    [2]A new View is returned and displayed(获取到后返回显示)

    那么如果我们有大量的数据需要显示的时候,每个Item都去重复执行getView中的创建新的View的动作吗?这样做会耗费大量的资源去执行重复的事情,实际上Android为我们提供了一套重复利用的机制叫做 原理简单描述下就是这样:

    在 一个完整的ListView第一次出现时,每个Item都是Null的,getView的时候会跑到需要inflate一个Item的代码段,假设整个 view只能最多显示10个item,那么当滑动到第11个Item的时候,第一个item会放入“recycler”,如果第11个Item和放入 “Recycler”的item的view一致,那么就会使用"Recycler"里面的Item来显示,从而不用再重复inflate一次,这样大大节 省了创建View的工作,在需要显示大量数据时显得尤为重要。

    工作原理的示意图如下:


    学习自http://android.amberfog.com/?p=296

    Demo:

    这是一个getView的方法,其他细节的Code就不显示了

     

    1. staticclass publicnull publicnull publicnull publicnull publicint ifnull null ifnull this"convertView == null,Then inflate and findViewById" thisfalse new else   
    2. this"convertView != null,Then findViewById(get Holder)" ifnull this"convertView != null,Then SetValue" int +id++mstr);  
    3. +name);  
    4. +url);  
    5. return     }  


     

    当我们第一次启动到Listview的时候如下,只显示了5个Item,那么getView被调用5次:

     


    打印的Log如下:可以看到从0-4都是null,我们需要做inflate的动作,

     

    1. </strong>  


    当我们小心往下滑动一个位置,刚出现第6个Item,此时第1个还没有消失时,

     


    这个时候只打印了一个获取第6个Item的Log,如下:可以看到第6个Item还是为null,需要inflate出来新的

     

    1. </strong>  


    如果此时再往下滑动列表,第1个item此时会放入Recycler,第7个Item此时不再是null,而是利用了第1个item的View,如下:

     


    从下面的Log,可以看到从第7个开始就不是null了

    01-12 18:52:36.243: ERROR/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.Java:69 getView ] - This is position:6

    01-12 18:52:36.243: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:89 getView ] - convertView != null,Then findViewById
    01-12 18:52:36.243: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:98 getView ] - convertView != null,Then SetValue
    01-12 18:52:36.693: ERROR/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:69 getView ] - This is position:7
    01-12 18:52:36.693: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:89 getView ] - convertView != null,Then findViewById
    01-12 18:52:36.693: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:98 getView ] - convertView != null,Then SetValue
    01-12 18:52:37.024: ERROR/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:69 getView ] - This is position:8
    01-12 18:52:37.024: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:89 getView ] - convertView != null,Then findViewById
    01-12 18:52:37.034: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:98 getView ] - convertView != null,Then SetValue
    01-12 18:52:37.604: ERROR/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:69 getView ] - This is position:9
    01-12 18:52:37.604: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:89 getView ] - convertView != null,Then findViewById
    01-12 18:52:37.604: DEBUG/MusicDemo(1272): @kesen@ [ main: Activity4Adapter.java:98 getView ] - convertView != null,Then SetValue

    等所有的item,一共10个都显示之后,不管上下滑动都再也不是NULL了,说明这个时候都是使用Recycle里面的view,而不会再重新inflate了,显然这样节省很多重复的操作

    【1】重复多轮调用getView的解决方案

    上面的例子我们可以看到,每滑动一次到需要显示的Item的时候就会调用一次 getView,理论上是10个Item,均显示一次的话是要调用getView() 10次的,那么为什么有时候很奇怪,10个item显示一次也许会调用getView 20次,甚至40-50次呢?我想肯定很多人都遇到过这个问题

    查了很久,其实我也没有找到root cause,只是知道我们在XML文件里面定义listView的时候需要设置height为fill_parent或者是指定的高度值(这个方法明显不靠谱,设置了高度,那么怎么进行不同屏幕的适配)

    所以推荐使用下面的,例如:

    <ListView android:id="@+id/activity04_list" android:layout_width="fill_parent" android:layout_height="fill_parent"/>

    网上有人解释说是因为ListView的Item的高度计算方法问题,试了下还是有效果的,希望之后有机会等了解原理后再来解释这个问题,我们可以先这也 使用,设置之后会发现没滑动出现一个item才会调用一次getView,这样是合理的调用,而不会出现只有10个item却调用几十次这样比较 tricky的事情,也节省了很多资源避免去重复做无用功。
    谢谢!

  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/1995hxt/p/5795399.html
Copyright © 2011-2022 走看看