转载 ANDROID LISTVIEW GETVIEW() 反复调用

最近作项目发现一个界面当有ListView是,getView和getCount中的log被疯狂调用。一个5个Item的ListView,getView居然会被反复调用7组。尤为是当ItemView中须要加载图片时,很容易形成GC过多,很容易出现ANR。 android

缘由就在于measure过程,ListView通常都会有好多个Item,并且也会同时显示若干组Item,这些Item的父元素都是这个ListView。 布局

更具Google的解释,View在Draw的时候分红两个阶段:measure和layout,在measure阶段时主要就是为了计算两个参数:height和width。并且要注意的是,这是个递归的过程,从顶向下,DecorView开始依次调用本身子元素的measure。计算完成这两个参数后就开始layout,最后再是draw的调用。 性能

对于ListView,固然每个Item都会被调用measure方法,而在这个过程当中getView和getCount会被调用,并且看用户的需求,可能会有不少次调用。 测试

而为何会有不少组次调用呢? 优化

问题就在于在layout中的决定ListView或者它的父元素的height和width属性的定义了。fill_parent会好一点,计算方法会比较简单,只要跟父元素的大小类似就行,可是即便是fill_parent,也不能给View当饭吃,仍是要计算出来具体的dip,因此measure仍是会被调用,只是可能比wrap_content的少一点。至于自适应的它会一直考量它的宽和高,根据内容(也就是它的子Item)计算宽高。可能这个measure过程会反复执行,若是父元素也是wrap_content,这个过程会更加漫长。 spa

因此,解决方法就是尽可能避免自适应,除非是万不得已,固定大小或者填充的效果会比较好一些。 设计

当咱们在使用listview的时候。有时候自定义adapter的时候,是否是会发如今getview里打印日志的时候,重复调用不少次?有时候4次。有的严重甚至到10次,当咱们在listview中移动的时候。每移动一列都会调用不少次,这样大大影响到效率!其实这和listview自己在android上的机制有关。下面我开始来介绍一下吧: 日志

在布局,咱们只有一个listview的时候。那好。咱们把高设置成wrap_content的时候。在listview里加载几行看看。日志在getview里打印一下。是否是重复调用了?那这个办法就好弄了。把高设置成fill_parent就成了。这个时候发现日志仍是重复调用?那就要看一下Listview的上一级而已的高是否是也是设置也fill_parent的,若是不是。请改动吧。若是是。。。那我还真没碰到重复调用的!由于测试好几回了!

 若是咱们在而已里不仅一个Listview。一个复杂好看的布局可能有不少。listview在布局的某个地方。这个时候有时候运气很差。你会发现你调用了不少次getview。我测试的时候。最高230次。。。可想而知。这个速度是至关慢。并且每移动一次就是调用这么屡次!对于这样的状况,在修改布局的时候,要考虑如下两点:1.首先考虑需求布局和性能哪一个更重要一点。2.考虑listview周边哪一个布局控件影响到了它!

 若是在性能上没有太大影响,而需求要求必需是那样的布局。那就以布局为主。看看有没有别的方法来优化一下listview,固然前提是布局一点都不能调整。若是能调整,布局没有太大变更。而listview又能很好的优化。那就固然优化了!当咱们优化的时候。首先要看一下有没有影响到Listview重绘的控件,好比。若是它上面和下面都有控件。并且高都是wrap_content,那么你就要设置成fill_parent或者固定高。这样listview在高上就不会重绘,这是最主要的一点。那左右是否是也有控件(通常一个手机页面用到list的时候不会有这么多控件)?有,那咱们就也要调整,那就同高同样的设置。必定要让listview是一个固定在那个地方不动的。否则,你就等着让他重复去调用吧!

 其实说了这么多。最主要的仍是在咱们进行布局的时候。要巧妙的运用每一个控件的属性,以及了解控件每一个的原理。这样在咱们进行UI设计的时候,才能很好的去结合! 递归

相关文章
相关标签/搜索