Question

I'm using GalleryView with ~40 images, and so slow because no recycling...

Anyone can show me a basic recycling to GalleryView on getView method.

public class ImageAdapter extends BaseAdapter {
    int mGalleryItemBackground;
    private Context mContext;

    private Integer[] mImageIds = {
            R.drawable.sample_1,
            R.drawable.sample_2,
            R.drawable.sample_3,
            R.drawable.sample_4,
            R.drawable.sample_5,
            R.drawable.sample_6,
            R.drawable.sample_7
    };

    public ImageAdapter(Context c) {
        mContext = c;

        TypedArray a = c.obtainStyledAttributes(R.styleable.HelloGallery);
        mGalleryItemBackground = a.getResourceId(
                R.styleable.HelloGallery_android_galleryItemBackground, 0);
        a.recycle();
    }

    public int getCount() {
        return mImageIds.length;
    }

     public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView i = new ImageView(mContext);

        i.setImageResource(mImageIds[position]);
        i.setLayoutParams(new Gallery.LayoutParams(150, 100));
        i.setScaleType(ImageView.ScaleType.FIT_XY);
        i.setBackgroundResource(mGalleryItemBackground);

        return i;
    }
}
Was it helpful?

Solution

Instead of creating a new ImageView in getView you should convert the convertView to the view you want. Here is an example of one way to do it:

public View getView(int position, View cv, ViewGroup parent) {

    if (! convertView istanceof ImageView)
    {
        ImageView cv = new ImageView(mContext);
        cv.setLayoutParams(new Gallery.LayoutParams(150, 100));
        cv.setScaleType(ImageView.ScaleType.FIT_XY);
        cv.setBackgroundResource(mGalleryItemBackground);

    }
    cv.setImageResource(mImageIds[position]);

    return cv;
}

Simply convert the convertView to match what you want, but first make sure its the proper view type.

Update: You should also downsample the images before you display them. Lets assume that you have a 500x500 pixel image saved under res/drawable but the image is only going to take up 125x125 pixels on the screen. You need to downsample the image before you display it. To know how much you need to downsample the bitmap you must first get its size

int maxSize = 125; // make 125 the upper limit on the bitmap size
int resId; // points to bitmap in res/drawable

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true; // Only get the bitmap size, not the bitmap itself
BitmapFactory.decodeResource(c.getResources(), resId, opts);

int w = opts.outHeight, h = opts.outHeight;
int maxDim = (w>h)?w:h; // Get the bigger dimension

Now that we have the size calculate how much to downsample the image. If we have a 500x500 bitmap and we want a 125x125 bitmap we keep 1 out of every 4 pixels which we get from int inSample = 500/125;

int inSample = maxDim/maxSize; 

opts = new BitmapFactory.Options();
opts.inSampleSize = inSample;

Now simply decode the resources and we have our down-sampled bitmap.

Bitmap b = BitmapFactory.decodeResource(c.getResources(), resId, opts);

Keep in mind that the original bitmap is unaffected. You can decode the image again and set opts.inSampleSize to 1 and you will get the entire 500x500 bitmap image.

OTHER TIPS

The Gallery widget actually has a bug that causes it to always return a null convertView. This means that even if you implement a getView method that uses the convertView you aren't going to gain performance because its always going to create a new one anyway.

Check out this answer

For one possible solution. This person basically took the Gallery widget and made the needed corrections to it. You can download the EcoGallery and include it in your own package so that you can use a Gallery Widget that properly recycles. You'r other options are: (1) Implement your own logic to hold and use a cache of View objects. (2) Find some other combination of View widgets to achieve an effect similar to the gallery and use them instead of the actual Gallery Widget.

Note that if you choose to download this EcoGallery you need the 3 java files listed on the site, and you'll have to grab 2 different xml files from inside your sdk and include them in your project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top