Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
927 views
in Technique[技术] by (71.8m points)

performance - Android GalleryView Recycling

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;
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...