In gridview adapter, getView(position == 0) was invoked too many times to measure layout when setImageBitmap() in a loader

后端 未结 4 1461
暖寄归人
暖寄归人 2021-02-05 05:26

I have a GridView for showing some icons.

BEFORE I had read this Displaying Bitmaps Efficiently from Android developer site, I was decoding bitmap from loca

4条回答
  •  有刺的猬
    2021-02-05 05:59

    isLayoutRequested is just there to tell you if a layout is already pending for this View. That is, after requestLayout is called, isLayoutRequested will return true until the next layout pass completes. The only reason for this check in requestLayout is to avoid repeatedly calling requestLayout on the parent if it's about to do layout anyway. isLayoutRequested is a red herring here: it's not the cause of onMeasure being called repeatedly.

    The root problem is that ImageView requests a new layout whenever you change its drawable. This is necessary for two reasons:-

    1. The size of the ImageView might depend on that of the drawable, if adjustViewBounds is set. This might in turn affect the sizes of other views, depending on the layout: the ImageView doesn't itself have enough information to know.
    2. ImageView.onMeasure is responsible for working out how much the drawable has to be resized to fit in the ImageView's bounds, according to the scale mode. If the new drawable isn't the same size as the old drawable, the ImageView must be measured again to recompute the required scaling.

    You can only fix the problem of having too many loaders by keeping a local cache of Bitmaps returned by the loaders. The cache might have all the Bitmaps if you know there aren't that many, or just the n most recently used ones. In your getView, first check if the Bitmap for that item exists in the cache, and if so, return an ImageView already set to that Bitmap. Only if it's not in the cache do you need to use a loader.

    Be careful: if the underlying data can change, you now need to make sure to invalidate the cache at the same time as calling invalidate on the GridView or notifying through ContentResolver. I've used some homebrew code to achieve this in my app, and it works nicely for me, but the good folks at Square have an open-source library called Picasso to do all the hard work for you if you prefer.

提交回复
热议问题