I would like to create an deferred loading adapter for use with a Gallery
widget.
That is to say getView()
returns an ImageView
I have an answer for you!
When any of the setImage...
methods are called on ImageView
in internally a layout pass is requested, for example, setImageBitmap()
as above is defined as such
public void setImageBitmap(Bitmap bm) {
setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
which calls
public void setImageDrawable(Drawable drawable) {
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
updateDrawable(drawable);
requestLayout(); //layout requested here!
invalidate();
}
}
which has the effect of the gallery 'snapping' to the center of the image thats currently closest to the center of the gallery.
What I have done to prevent this is have the View thats loading into the Gallery have a explicit height and width (in dip
s) and using an ImageView
subclass that ignores layout requests. This works as the gallery still has a layout pass initially but does not bother doing this every time an image in the gallery changes, which I imagine would only need to happen if the gallery views had their width and height set to WRAP_CONTENT
, which we dont. Note that as invalidate()
is still called in setImageDrawable()
the image will still be drawn when set.
My very simple ImageView
subclass below!
/**
* This class is useful when loading images (say via a url or file cache) into
* ImageView that are contained in dynamic views (Gallerys and ListViews for
* example) The width and height should be set explicitly instead of using
* wrap_content as any wrapping of content will not be triggered by the image
* drawable or bitmap being set (which is normal behaviour for an ImageView)
*
*/
public class ImageViewNoLayoutRefresh extends ImageView
{
public ImageViewNoLayoutRefresh(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public ImageViewNoLayoutRefresh(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ImageViewNoLayoutRefresh(Context context)
{
super(context);
}
@Override
public void requestLayout()
{
// do nothing - for this to work well this image view should have its dims
// set explicitly
}
}
edit: i should mention that the onItemSelected approaches can also work, but as I needed to hook into that while flinging was taking place I came up with the above, which I think is more flexible approach