问题
I have been suffering this issue for months and months (but now I am performance tuning). However, I now desperately need to know why my adapter feels it is necessary to run bindView
up to 4 times on a record.
I have a custom cursor adapter that populates a gridview.
Some debug to show what's going on:
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...
The "Avatar empty..." and "Picture creation..." is simply debug that tells me it is processing and updating 2 particular ImageView
s.
Why o why is bindView
running so many times? What are the reasons for this and what can I do to resolve this?
Logically speaking I expect bindView
to run once (and once each time the adapter is updated), am I wrong in thinking this?
回答1:
The operating system may call bindView
multiple times so that it can measure and lay out the list correctly. This is not a bug so much as the way it has to be. This, along with smoothness of scrolling, is why bindView
implementations need to be as efficient as possible. There are some nice tips and tricks you can use detailed on the Android Developers Page.
回答2:
I also found that bindView was being called many more times than expected. My ListView height was set to wrap_content. After changing it to match_parent the number of calls reduced drastically.
Credit for this solution goes to the answer for this question Custom CursorAdapater's bindView called 77 times...have I done something wrong?
回答3:
One thing I discovered with ImageView
is that changing the image will cause the ImageView
to request a layout unless the new and old image are exactly the same size.
Internally the ImageView
uses getIntrinsicWidth()
and getIntrinsicHeight()
to work out whether or not to request a layout.
Try something like this (although it would make more sense to send the current width/height to your async load and resize the bitmap before returning from the background):
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);
}
来源:https://stackoverflow.com/questions/15297323/custom-cursor-adapter-calling-bindview-multiple-times