Custom cursor adapter calling bindView multiple times

南笙酒味 提交于 2019-12-10 02:09:58

问题


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 ImageViews.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!