ListView使用注意事项

不要把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刷新顺序也会反过来。

你可能感兴趣的:(ListView使用注意事项)