android ListView 在初始化时多次调用getView()原因分析

转载 2015年07月06日 23:44:56

本文转自:http://www.cnblogs.com/linjzong/p/3494090.html

 今天在做一个功能:在初始化ListView时,把第一行背景置为黄色,同时保存第一行对象,用于在点击其他行时将该行重新置为白色。

if(position==0){
                convertView.setBackgroundColor(Color.YELLOW);
                lastconvertView=convertView;
            }

 

结果运行时发现第一行的颜色一直会是黄色而无法改变。调试了之后发现getView中 if(position==0) 居然会多次进入,最终导致的结果便是我最后一次取得的lastconvertView并非listview上面的第一行。网上查了之后发现原因是因为未固定listview的高度导致的,但是root cause却找不到说明。于是去翻阅了源码+大量调试,大概推算出了原因,在此记录。

首先是说明下ListView的显示机制,listview的机制是这样子的:

假如你有1000条数据,但是屏幕只能显示10条,那么当你第一次加载显示的时候,会先创建10个View,1-10,当你拖动Listview,使1隐藏而11显示的时候,系统会自动把填充1的View传递过来,注意看代码Adapter的getView方法

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

这里的converView就是1的view,一般的做法会把这个view拿来复用,作为11的view。

 

当我们固定listview的高度时(fill_parent或直接固定高度),那么listview很容易就能计算出容器内可以显示多少行。但如果我们使用了“wrap_content”,只有在屏幕内控件完全加载后才知道到底能显示多少行数据时,ListView自身便会做一些尝试性计算。在源码中可以发现一些叫做onMeasure的方法,目测是做此用处(源码略显复杂,没读透)。

当listview计算出屏幕一共需要多少行后,如果listview自身高度不变,那么它的容纳的行数就不会变,使用getChildCount()可以得到它的最大行数。

再回到原来的问题,为什么最后一次取得的结果不是listview的第一行呢? 将listview设置为“wrap_content”后用下面的测试代码,看下输出。

复制代码
//获取当前listview的个数 相等输出个数和站点名 不相等输出个数和"无"
            if(listView.getChildCount() == position)
            {
                //child个数 当前position位置 +站名
                Log.i("", listView.getChildCount()+" "+position+" "+coordInfo.stationname);
            }
            else {
                //child个数 当前position位置+无
                Log.i("", listView.getChildCount()+" "+position+" "+"无");
            }
复制代码

在我的测试应用中,listview刚好可以放11个view,看下输出发现,listview在开始时,实例化了11个view进行填充,即前面10个“无”结尾的+第一个”客运中心“结尾的view,由此测量出了listview的容量。换句话说,这11个view都只是用于测量的临时view。另外在正是填充完之后,listview再次创建了11个临时view用于确认高度是否正确。而由于我的代码逻辑设计失误,在

进行到这一步时,由于position会再次等于0,因此会把一个临时的view赋值给lastconvertView。

到此原因找到,同时将listview的高度设为fill_parent后,问题解决。

 

另外说下网上说的另外一个解决方法

复制代码
if(parent.getchildcount() == position)
{
       正常情况下应该执行的代码
}
else
{
     这里就是多次加载的问题,可以不用理这里面的 代码,
}
复制代码

这个方法是不可行的,因为在不改变listview高度的情况下,listview的getchildcount()在加载完成后是固定的,position指的却是在adapter中的位置,当adapter的个数大于listview的容纳个数时,该判断条件不会成立,即滑动listview时,不会成立。


android中ListView多次重复执行getView的问题

以前倒是没有注意listview的getView会重复执行多次,这次因为布局比较复杂,所以在测试的时候去断点跟踪,发现同一条数据不断的重复执行。觉得很奇怪,于是上网搜索了一下。网上的解释基本一致,就是...
  • zrbcsdn
  • zrbcsdn
  • 2015年12月24日 13:05
  • 677

android ListView 在初始化时多次调用getView()原因分析

今天在做一个功能:在初始化ListView时,把第一行背景置为黄色,同时保存第一行对象,用于在点击其他行时将该行重新置为白色。 if(position==0){ ...
  • LAMP_zy
  • LAMP_zy
  • 2015年06月22日 22:33
  • 710

Android ListView优化之getView频繁多次调用与ViewHolder工作原理

Android中我们经常会用到ListView,然后ListView到底是如何通过ViewHolder去优化的? 1.常见的适配器中利用ViewHolder去优化ListView的代码 @Overri...
  • u010785585
  • u010785585
  • 2016年11月06日 20:26
  • 2924

listview 自定义 adapter getview()执行多次 或 N 次的问题

这两天特郁闷,listview 自定义了 adapter,在getview 打印 position,吓了我一跳,每秒N次打印,而且都是 0  1  2  0  1  2 。。。。,今天百度一下,发现一...
  • wblyuyang
  • wblyuyang
  • 2015年01月15日 11:27
  • 2020

关于ListView的getView方法被多次重复调用的问题

package com.pxy.demo.adapter; import java.util.ArrayList; import com.pxy.demo.R; import android.c...
  • LoveBugzzz
  • LoveBugzzz
  • 2016年09月17日 14:03
  • 2641

android之ListView多次调用getView解决办法

前言最近遇到一个bug,写了一个简单的listview,不过listview的条目内含的控件较多(且控件的状态即显隐状态也比较复杂),结果就导致了,一个bug,例如我的item只有3个,但是getVi...
  • dabaoonline
  • dabaoonline
  • 2016年08月01日 09:33
  • 1309

ListView和GridView多次调用GetView的现象和解决办法

背景:以前遇到过,最近又碰到了,就总结一下吧 一.ListView (1)出现原因 是因为listView的高度不确定,一般用的是wrap_content,导致系统需要不断地测量,也就是多测调用onM...
  • u011889786
  • u011889786
  • 2016年08月07日 17:12
  • 2713

ListView设置adapter时getView被多次调用

今天在做项目的时候,发现ListView在高度为wrap_content时,adater中的getView方法居然被调用了三次,于是在网上搜索 发现也有网友与我碰到的问题相同,但有的只是说把wrap...
  • jonloong
  • jonloong
  • 2015年12月16日 11:49
  • 3196

listview中嵌套gridview时候,getview多次调用的bug

当启动这个listview的时候,同一个item的图片会不断的变化,很是奇怪,于是在adapter中进行调试发现,      getview,执行了很多次,而且次数也不定,最后在网上发现说是由于li...
  • leehu1987
  • leehu1987
  • 2013年12月04日 15:28
  • 1182

彻底解决listview,gridview的getview多次调用问题

listview,gridview,有时候getview会调用多次,特别是把listview放在viewpager中,很容易卡顿 网上的方法往往只是说,把listview的height固定住...
  • ksr12333
  • ksr12333
  • 2014年01月17日 14:59
  • 18275
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android ListView 在初始化时多次调用getView()原因分析
举报原因:
原因补充:

(最多只允许输入30个字)