不要把ListView布局的layout_height设置为wrap_content
这样会让ListView每增加一个item都会重新计算高度,耗费时间。我们举个例子,做一个ListView,初始化两个item,编写getView代码如下
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if ( convertView == null ) {
Log.e("pengtao", "convertView == null, position = " + position);
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
Log.e("pengtao", "convertView != null, position = " + position);
}
viewHolder.tvText.setText(container.get(position));
return convertView;
}
第一次我们把ListView的布局高度设为wrap_content
。然后我们观察到如下打印日志
06-03 03:30:43.686 12721-12721/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
06-03 03:30:43.691 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
06-03 03:30:43.930 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 0
06-03 03:30:43.931 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
06-03 03:30:43.931 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 0
06-03 03:30:43.931 12721-12721/cn.hadcn.listview_test E/pengtao: convertView == null, position = 1
06-03 03:30:43.935 12721-12721/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
06-03 03:30:43.942 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
06-03 03:30:44.237 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 0
06-03 03:30:44.237 12721-12721/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
以上日志相当复杂,这是因为ListView的高度设置为了content_wrap
也就意味着,它需要不断计算自身高度来适应child的高度,而每次高度的变化都需要刷新整个ListView,这就导致了getView
方法被反复调用。我们再看下把wrap_content
改为match_parent
后的打印日志
06-03 03:40:23.131 29844-29844/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
06-03 03:40:23.138 29844-29844/cn.hadcn.listview_test E/pengtao: convertView == null, position = 1
很清晰,就两条。
transcriptMode属性对ListView刷新顺序的影响
在有些情况下,比如如果在用ListView实现聊天时,开发者肯能会把ListView的transriptMode设置为alwaysScroll
,这样在屏幕有刷新时,自动把ListView滚动到最后一栏。但这里有一个小点需要大家留意。这里我们还是用日志的形式让大家感受下,首先我们不设置alwaysScroll属性,当新增一个item然后调用Adapter的notifyDataSetChanged();
来刷新。
06-03 04:56:52.043 10722-10722/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
06-03 04:56:52.050 10722-10722/cn.hadcn.listview_test E/pengtao: convertView == null, position = 1
06-03 04:56:54.429 10722-10722/cn.hadcn.listview_test E/pengtao: convertView != null, position = 0
06-03 04:56:54.429 10722-10722/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
06-03 04:56:54.430 10722-10722/cn.hadcn.listview_test E/pengtao: convertView == null, position = 2
我们可以看到,日志在上面例子中的两条的基础上又增加了三条,表示又新增了一个栏目,并且也为它创建了一个convertView。下面我们加上android:transcriptMode="alwaysScroll"
,重复以上操作,会看到如下日志:
06-03 04:59:36.716 17986-17986/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
06-03 04:59:36.719 17986-17986/cn.hadcn.listview_test E/pengtao: convertView == null, position = 1
06-03 04:59:43.477 17986-17986/cn.hadcn.listview_test E/pengtao: convertView != null, position = 2
06-03 04:59:43.477 17986-17986/cn.hadcn.listview_test E/pengtao: convertView != null, position = 1
06-03 04:59:43.478 17986-17986/cn.hadcn.listview_test E/pengtao: convertView == null, position = 0
前两条还是一样,但后三条的顺序与上面想法,并且被刷新的item是第一条位置上的,而不是我们刚刚加入的。也就是我们在设置alwaysScroll属性后,ListView刷新顺序也会反过来。