了解convertView

时间:2014-03-30 05:17:55

标签: android android-listview custom-adapter

我试图了解convertView的工作原理。我确实阅读了我遇到的大部分文档以及StackOverflow上的问题。我以为我已经理解它是如何工作的,但是当涉及到实现时,我无法理解它。

截至目前我的代码:

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

    if(Const.DEBUGGING){
        Log.d(Const.DEBUG, "Position = "+position);
    }

    if (convertView == null) {

        if(Const.DEBUGGING){
            Log.d(Const.DEBUG, "convertView is NULL");
        }

        convertView = getActivity().getLayoutInflater().inflate(
                R.layout.item_mtf_results, parent, false);

        holder = new ViewHolder();
        holder.txtViewResults = (TextView) convertView
                .findViewById(R.id.textview_item_mtf_results);

        convertView.setTag(holder);
    } else {

        if(Const.DEBUGGING){
            Log.d(Const.DEBUG, "convertView is NOT Null");
        }

        holder = (ViewHolder) convertView.getTag();
    }

    holder.txtViewResults.setText(dummyText[position]);

    return convertView;
}

我的Logcat以上代码:

03-30 10:27:29.433: D/TYM(29043): Position = 0
03-30 10:27:29.433: D/TYM(29043): convertView is NULL
03-30 10:27:29.433: D/TYM(29043): Position = 1
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 2
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 3
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 4
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 5
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 6
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 7
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.433: D/TYM(29043): Position = 8
03-30 10:27:29.433: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.453: D/TYM(29043): Position = 0
03-30 10:27:29.453: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.453: D/TYM(29043): Position = 1
03-30 10:27:29.453: D/TYM(29043): convertView is NULL
03-30 10:27:29.453: D/TYM(29043): Position = 2
03-30 10:27:29.453: D/TYM(29043): convertView is NULL
03-30 10:27:29.453: D/TYM(29043): Position = 3
03-30 10:27:29.453: D/TYM(29043): convertView is NULL
03-30 10:27:29.453: D/TYM(29043): Position = 4
03-30 10:27:29.453: D/TYM(29043): convertView is NULL
03-30 10:27:29.463: D/TYM(29043): Position = 5
03-30 10:27:29.463: D/TYM(29043): convertView is NULL
03-30 10:27:29.463: D/TYM(29043): Position = 6
03-30 10:27:29.463: D/TYM(29043): convertView is NULL
03-30 10:27:29.463: D/TYM(29043): Position = 7
03-30 10:27:29.463: D/TYM(29043): convertView is NULL
03-30 10:27:29.463: D/TYM(29043): Position = 8
03-30 10:27:29.463: D/TYM(29043): convertView is NULL
03-30 10:27:29.503: D/TYM(29043): Position = 0
03-30 10:27:29.503: D/TYM(29043): convertView is NULL
03-30 10:27:29.503: D/TYM(29043): Position = 1
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 2
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 3
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 4
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 5
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 6
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 7
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null
03-30 10:27:29.503: D/TYM(29043): Position = 8
03-30 10:27:29.503: D/TYM(29043): convertView is NOT Null

截图:

enter image description here

根据我对convertView的理解,第一次在ListView中加载项目时,内存仅分配给屏幕中加载的视图,还有一些额外的缓冲区。当我们开始滚动时,屏幕外的视图将被回收到现有视图中。

因此,当屏幕第一次加载时,convertView将为NULL,因此分配了内存。当我们开始滚动并且视图可用于回收时,convertView将不会为空。这是对的吗?

上面的Logcat第一次显示我加载屏幕时的日志。

我的问题:

  1. 为什么所有观看次数都有3次。刚装载屏幕第一次......
  2. 为什么convertView NOT NULL在第二个位置?
  3. 为什么convertView在第二个周期再次为NULL?

1 个答案:

答案 0 :(得分:1)

为了更好地理解要做什么,在getView()中放置一个调试器断点并检查调用堆栈跟踪以查看调用的原因。

您的ListView似乎处于复杂的布局中,需要多次测量/布局传递。例如。 LinearLayout的权重或RelativeLayout与子女之间存在依赖关系。

要测量ListView,必须测量可见的孩子。这解释了对getView()的一次调用,以及两次布局的两次调用。此外,出于测量目的,视图可以立即回收,因为它们不需要在屏幕上显示。

道德:避免将适配器视图放在多遍布局中。如果可能,也要避免使用多遍布局。