自定义游标适配器多次调用bindView

时间:2013-03-08 15:21:15

标签: android android-gridview android-cursoradapter

我已经遭受了这个问题数月和数月(但现在我正在进行性能调整)。但是,我现在迫切需要知道为什么我的适配器认为有必要在记录上运行bindView最多4次。

我有一个填充网格视图的自定义光标适配器。

进行一些调试以显示正在发生的事情:

03-08 14:46:47.980: I/AdapterCursorGrid(20724): newView()
03-08 14:46:48.470: I/AdapterCursorGrid(20724): bindView()
03-08 14:46:48.570: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Record Id: 1
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() View Type: 0
03-08 14:46:48.570: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:48.600: D/AdapterCursorGrid(20724): bindView() Avatar empty...
03-08 14:46:48.690: D/AdapterCursorGrid(20724): bindView() Picture creation...
03-08 14:46:49.490: I/AdapterCursorGrid(20724): bindView()
03-08 14:46:49.501: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Record Id: 1
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() View Type: 0
03-08 14:46:49.501: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Avatar empty...
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Picture creation...
03-08 14:46:50.320: I/AdapterCursorGrid(20724): newView()
03-08 14:46:51.170: I/AdapterCursorGrid(20724): bindView()
03-08 14:46:51.180: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Record Id: 1
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0
03-08 14:46:51.190: I/AdapterCursorGrid(20724): bindView() View Type: 0
03-08 14:46:51.190: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:51.190: D/AdapterCursorGrid(20724): bindView() Avatar empty...
03-08 14:46:51.200: D/AdapterCursorGrid(20724): bindView() Picture creation...
03-08 14:46:51.870: I/AdapterCursorGrid(20724): bindView()
03-08 14:46:51.896: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:51.896: I/AdapterCursorGrid(20724): bindView() Record Id: 1
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() View Type: 0
03-08 14:46:51.900: I/AdapterCursorGrid(20724): --------------------------
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Avatar empty...
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Picture creation...

“Avatar empty ...”和“Picture creation ...”只是调试,告诉我它正在处理和更新2个特定的ImageView

为什么bindView运行这么多次?这是什么原因,我该怎么做才能解决这个问题?

从逻辑上讲,我希望bindView能够运行一次(每次更新适配器一次),我想错了吗?

3 个答案:

答案 0 :(得分:13)

操作系统可能会多次调用bindView,以便它可以正确地测量和布置列表。这不是一个错误,就像它必须的那样。这与滚动的平滑性是bindView实现需要尽可能高效的原因。您可以使用Android Developers Page详细介绍一些很好的提示和技巧。

答案 1 :(得分:11)

我还发现bindView的调用次数比预期多得多。我的ListView高度设置为wrap_content。将其更改为match_parent后,呼叫数量急剧减少。

此解决方案的功劳归结为此问题的答案Custom CursorAdapater's bindView called 77 times...have I done something wrong?

答案 2 :(得分:0)

我在ImageView发现的一件事是,更改图片会导致ImageView请求布局,除非新旧图片的大小完全相同。

ImageView内部使用getIntrinsicWidth()getIntrinsicHeight()来确定是否要求布局。

尝试这样的事情(尽管将当前宽度/高度发送到异步加载并在从背景返回之前调整位图大小更有意义):

public void replaceBitmap(ImageView iv, Bitmap bitmap) {
    Drawable current = iv.getDrawable();
    if (bitmap.getWidth() != current.getIntrinsicHeight()
            || bitmap.getHeight() != current.getIntrinsicHeight()) {
        bitmap = Bitmap.createScaledBitmap(bitmap,
            current.getIntrinsicWidth(), current.getIntrinsicHeight(), true);
    }
    iv.setImageBitmap(bitmap);
}