Xamarin有效地为Gridview加载位图

时间:2017-01-23 17:36:50

标签: android memory-management xamarin

所以我看到了这个关于有效加载大位图的xamarin文档。然而我正在努力为gridview实现它。

https://developer.xamarin.com/recipes/android/resources/general/load_large_bitmaps_efficiently/

那么我们如何为gridview的适配器实现它呢?

先谢谢你。

1 个答案:

答案 0 :(得分:2)

  

那么我们如何为gridview的适配器实现它呢?

您可以创建一个类(下面为ThumbImageFactory)来包装文档中提到的所有函数:

public class ThumbImageFactory
{
    public readonly Context context;
    public ThumbImageFactory(Context c)
    {
        context = c;
    }

    public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
    {
        // Raw height and width of image
        float height = options.OutHeight;
        float width = options.OutWidth;
        double inSampleSize = 1D;

        if (height > reqHeight || width > reqWidth)
        {
            int halfHeight = (int)(height / 2);
            int halfWidth = (int)(width / 2);

            // Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway.
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
            {
                inSampleSize *= 2;
            }

        }
        return (int)inSampleSize;
    }

    public  Bitmap LoadScaledDownBitmapForDisplay(Resources res, BitmapFactory.Options options, int reqWidth, int reqHeight,int resourceId)
    {
        // Calculate inSampleSize
        options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.InJustDecodeBounds = false;

        return BitmapFactory.DecodeResource(res, resourceId, options);
    }

    public BitmapFactory.Options GetBitmapOptionsOfImage(int resourceId)
    {
        BitmapFactory.Options options = new BitmapFactory.Options
        {
            InJustDecodeBounds = true
        };

        // The result will be null because InJustDecodeBounds == true.
        Bitmap result = BitmapFactory.DecodeResource(context.Resources, resourceId, options);


        int imageHeight = options.OutHeight;
        int imageWidth = options.OutWidth;


        return options;
    }
}

在适配器中创建一个ThumbImageFactory实例并调用GetView中的函数:

public class ImageAdapter : BaseAdapter
{
    private readonly Context context;
    private ThumbImageFactory thumbFactory;

    public ImageAdapter(Context c)
    {
        context = c;
        thumbFactory = new ThumbImageFactory(c);
    }
    ...
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        ImageView imageView;
        if (convertView == null)
        {
            imageView = new ImageView(this.context);
            imageView.LayoutParameters = new AbsListView.LayoutParams(150, 150);
            imageView.SetScaleType(ImageView.ScaleType.CenterCrop);
            imageView.SetPadding(0, 0, 0, 0);
        }
        else
        {
            imageView = (ImageView)convertView;
        }

        Bitmap bitmap = GetThumbImage(thumbIds[position]);
        imageView.SetImageBitmap(bitmap);
        return imageView;
    }

    public  Bitmap GetThumbImage(int resourceId)
    {
        BitmapFactory.Options options = thumbFactory.GetBitmapOptionsOfImage(resourceId);
        Bitmap bitmap=thumbFactory.LoadScaledDownBitmapForDisplay(context.Resources, options, 150, 150, resourceId);
        return bitmap;
    }
}

注意:我们无法将GetView修改为异步,因此我将文档中的所有函数更改为同步函数。这是完整的Demo