可以看到,当用户点击Gallery中某一项时,触发onItemClick事件,在其中,我们通过根据该缩略图对应的Image_ID来从MediaStore.Images.Media中查询该缩略图对应的大图。并在ImageButton中显示。
这里当图片很多时,可能会出现内存溢出,为了避免这种情况,可以更加Gallery的特点,使用缓存。保存当前可见的缩略图的前三个到后三个。其余的全部recycle。当用户点击Gallery的时候,在判断当前的位置,如果大于或小于某个值时,则重新更新缓存。这样保证内存中的缩略图的个数总是6+Gallery.getLastVisiblePosition-Gallery.getFirstVisiblePosition个。其实这就是浮动缓存窗口,一个固定大小窗口在整个坐标(全部缩略图)上游动。这里没有实现,以后待续。
同时,你可能已经注意到,程序中使用到了一个BitmapUtils类,这个类是封装了一系列对查询图片,并将其解析为Bitmap的类。
代码如下:
package com.liner.manager; import java.util.ArrayList; import java.util.List; import Android.app.Activity; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.provider.MediaStore; import android.util.Log; public final class BitmapUtils { public static Bitmap decodeBitmap(String path, int displayWidth, int displayHeight){ BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(path, op); //获取尺寸信息 //获取比例大小 int wRatio = (int)Math.ceil(op.outWidth/(float)displayWidth); int hRatio = (int)Math.ceil(op.outHeight/(float)displayHeight); //如果超出指定大小,则缩小相应的比例 if(wRatio > 1 && hRatio > 1){ if(wRatio > hRatio){ op.inSampleSize = wRatio; }else{ op.inSampleSize = hRatio; } } op.inJustDecodeBounds = false; bmp = BitmapFactory.decodeFile(path, op); return Bitmap.createScaledBitmap(bmp, displayWidth, displayHeight, true); } /** * 采用复杂计算来决定缩放 * @param path * @param maxImageSize * @return */ public static Bitmap decodeBitmap(String path, int maxImageSize){ BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(path, op); //获取尺寸信息 int scale = 1; if(op.outWidth > maxImageSize || op.outHeight > maxImageSize){ scale = (int)Math.pow(2, (int)Math.round(Math.log(maxImageSize/(double)Math.max(op.outWidth, op.outHeight))/Math.log(0.5))); } op.inJustDecodeBounds = false; op.inSampleSize = scale; bmp = BitmapFactory.decodeFile(path, op); return bmp; } public static Cursor queryThumbnails(Activity context){ String[] columns = new String[]{ MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID }; return context.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.Images.Thumbnails.DEFAULT_SORT_ORDER); } public static Cursor queryThumbnails(Activity context, String selection, String[] selectionArgs){ String[] columns = new String[]{ MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID }; return context.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns, selection, selectionArgs, MediaStore.Images.Thumbnails.DEFAULT_SORT_ORDER); } public static Bitmap queryThumbnailById(Activity context, int thumbId){ String selection = MediaStore.Images.Thumbnails._ID + " = ?"; String[] selectionArgs = new String[]{ thumbId+"" }; Cursor cursor = BitmapUtils.queryThumbnails(context,selection,selectionArgs); if(cursor.moveToFirst()){ String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA)); cursor.close(); return BitmapUtils.decodeBitmap(path, 100, 100); }else{ cursor.close(); return null; } } public static Bitmap[] queryThumbnailsByIds(Activity context, Integer[] thumbIds){ Bitmap[] bitmaps = new Bitmap[thumbIds.length]; for(int i=0; i<bitmaps.length; i++){ bitmaps[i] = BitmapUtils.queryThumbnailById(context, thumbIds[i]); } return bitmaps; } /** * 获取全部 * @param context * @return */ public static List<Bitmap> queryThumbnailList(Activity context){ List<Bitmap> bitmaps = new ArrayList<Bitmap>(); Cursor cursor = BitmapUtils.queryThumbnails(context); for(int i=0; i<cursor.getCount(); i++){ cursor.moveToPosition(i); String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA)); Bitmap b = BitmapUtils.decodeBitmap(path, 100, 100); bitmaps.add(b); } cursor.close(); return bitmaps; } public static List<Bitmap> queryThumbnailListByIds(Activity context, int[] thumbIds){ List<Bitmap> bitmaps = new ArrayList<Bitmap>(); for(int i=0; i<thumbIds.length; i++){ Bitmap b = BitmapUtils.queryThumbnailById(context, thumbIds[i]); bitmaps.add(b); } return bitmaps; } public static Cursor queryImages(Activity context){ String[] columns = new String[]{ MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME }; return context.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER); } public static Cursor queryImages(Activity context, String selection, String[] selectionArgs){ String[] columns = new String[]{ MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME }; return context.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, selectionArgs, MediaStore.Images.Media.DEFAULT_SORT_ORDER); } public static Bitmap queryImageById(Activity context, int imageId){ String selection = MediaStore.Images.Media._ID + "=?"; String[] selectionArgs = new String[]{ imageId + "" }; Cursor cursor = BitmapUtils.queryImages(context, selection, selectionArgs); if(cursor.moveToFirst()){ String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); cursor.close(); //return BitmapUtils.decodeBitmap(path, 260, 260); return BitmapUtils.decodeBitmap(path, 220); //看看和上面这种方式的差别,看了,差不多 }else{ cursor.close(); return null; } } /** * 根据缩略图的Id获取对应的大图 * @param context * @param thumbId * @return */ public static Bitmap queryImageByThumbnailId(Activity context, Integer thumbId){ String selection = MediaStore.Images.Thumbnails._ID + " = ?"; String[] selectionArgs = new String[]{ thumbId+"" }; Cursor cursor = BitmapUtils.queryThumbnails(context, selection, selectionArgs); if(cursor.moveToFirst()){ int imageId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID)); cursor.close(); return BitmapUtils.queryImageById(context, imageId); }else{ cursor.close(); return null; } } }这样就实现了,类似百度图片浏览的效果。效果图如下: