2

我正在使用带有约 40 张图像的 GalleryView,而且速度很慢,因为没有回收......

GalleryView任何人都可以向我展示一个基本的回收getView方法。

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;
    }
}
4

2 回答 2

5

而不是创建一个新ImageView的,getView你应该将其转换为convertView你想要的视图。这是一种方法的示例:

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;
}

只需将 convertView 转换为您想要的,但首先要确保它是正确的视图类型。

更新:您还应该在显示图像之前对图像进行下采样。假设您保存了一个 500x500 像素的图像,res/drawable但该图像在屏幕上仅占用 125x125 像素。您需要在显示之前对图像进行下采样。要知道您需要对位图进行多少下采样,您必须首先获取它的大小

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

现在我们有了大小,可以计算对图像进行下采样的程度。如果我们有一个 500x500 的位图并且我们想要一个 125x125 的位图,我们会从我们得到的每 4 个像素中保留 1 个int inSample = 500/125;

int inSample = maxDim/maxSize; 

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

现在只需对资源进行解码,我们就有了下采样位图。

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

请记住,原始位图不受影响。您可以再次解码图像并设置opts.inSampleSize1,您将获得整个 500x500 位图图像。

于 2011-10-17T18:11:20.677 回答
4

Gallery 小部件实际上有一个错误,导致它始终返回 null convertView。这意味着即使你实现了一个使用 convertView 的 getView 方法,你也不会获得性能,因为它总是会创建一个新的。

看看这个答案

对于一种可能的解决方案。这个人基本上拿走了画廊小部件并对其进行了必要的更正。您可以下载 EcoGallery 并将其包含在您自己的包中,以便您可以使用正确回收的 Gallery Widget。您的其他选择是: (1) 实现您自己的逻辑来保存和使用 View 对象的缓存。(2) 找一些其他的 View 小部件组合来达到类似画廊的效果,并使用它们来代替实际的画廊小部件。

请注意,如果您选择下载此 EcoGallery,您需要网站上列出的 3 个 java 文件,并且您必须从您的 sdk 中获取 2 个不同的 xml 文件并将它们包含在您的项目中。

于 2011-10-17T19:33:25.567 回答