从getView()重复调用浅谈listview数据装载机制

来源:互联网 发布:觉醒字幕组知乎 编辑:程序博客网 时间:2024/05/21 15:13

公司的一个项目装载数据用到listview,本来是很简单的事,在数据装载的时候对第一条数据的上竖线进行隐藏,对最后一条数据的下竖线进行隐藏,
期望效果图:
这里写图片描述
大家看一下我的代码:

@Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;               Log.i("外侧---------:","getChildCount():"+parent.getChildCount()+" position:"+position);        if (convertView == null) {            Log.i("内侧:","getChildCount():"+parent.getChildCount()+" position:"+position);            convertView = inflater.inflate(R.layout.item_main, null);            holder = new ViewHolder();            holder.top_icon = (ImageView) convertView                    .findViewById(R.id.top_icon);            holder.top_line = (ImageView) convertView                    .findViewById(R.id.top_line);            holder.bottom_line = (ImageView) convertView                    .findViewById(R.id.bottom_line);            holder.baifen = (TextView) convertView.findViewById(R.id.baifen);            holder.text_finish = (TextView) convertView                    .findViewById(R.id.text_finish);            holder.time = (TextView) convertView.findViewById(R.id.time);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        if (position == 0) {            holder.top_line.setVisibility(View.INVISIBLE);        }        if (position == getCount() - 1) {            holder.bottom_line.setVisibility(View.INVISIBLE);        }        holder.text_finish.setText(list.get(position));        return convertView;    }

结果出现的效果图:
这里写图片描述
下图是对上下竖线不进行隐藏的效果图:
这里写图片描述
当时非常困惑,为什么第一个item的下竖线消失了,结果通过打印日志和反复查看源码,对listview装载又有了新认识,不得不承认listview源码得强大:
1、getview刚开始只是获得第一个item view对象,而后通过不断地重用该view 进行屏幕的测量,主要是为了验证一个屏幕到底能够填充多少个item 所以此时不会真正的布局到屏幕上,所以listview.getChildCount会一直等于0,直到测量结束后(有时候会反复多次重复测量,调整item大小),才会进行布局。看一下下图的日志:
这里写图片描述
2、测试完装载数量后,进行listview装载,也就是屏幕装载,此时由于第一个item最开始就新建了,所以convertview不为空,而其他的item会被新建
这里写图片描述
而我的试图之所以会出现第一个item下线消失是,在首次测量的时候执行到第五个view的时候由于不会重建,所以依旧调用的是第一个view ,因而会执行
if (position == getCount() - 1) {
holder.bottom_line.setVisibility(View.INVISIBLE);
}
所以正确的方式应该是

if (position == 0) {            holder.top_line.setVisibility(View.INVISIBLE);        }else {            holder.top_line.setVisibility(View.VISIBLE);        }        if (position == getCount() - 1) {            holder.bottom_line.setVisibility(View.INVISIBLE);        }else {            holder.bottom_line.setVisibility(View.VISIBLE);        }        holder.text_finish.setText(list.get(position));        return convertView;
0 0
原创粉丝点击