我已经遭受了这个问题数月和数月(但现在我正在进行性能调整)。但是,我现在迫切需要知道为什么我的适配器认为有必要在记录上运行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
能够运行一次(每次更新适配器一次),我想错了吗?
答案 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);
}