美文网首页android学习之路
ListView使用注意事项

ListView使用注意事项

作者: CPPAlien | 来源:发表于2016-10-25 11:52 被阅读107次

    不要把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使用注意事项

        本文链接:https://www.haomeiwen.com/subject/isxldttx.html