android仿最新6.2版本微信相册

仿微信相册选择图片,查看大图,写的不太好,希望评论指出不足,谅解,先介绍一下我的基本思路

第一步获取手机上的所有图片路径:

Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;ContentResolver contentResolver = getContentResolver();//获取jpeg和png格式的文件,并且按照时间进行倒序Cursor cursor = contentResolver.query(uri, null, MediaStore.Images.Media.MIME_TYPE + "=\&;image/jpeg\&; or " +MediaStore.Images.Media.MIME_TYPE + "=\&;image/png\&;", null, MediaStore.Images.Media.DATE_MODIFIED+" desc");if (cursor != null){while (cursor.moveToNext()){//do something}handler.sendEmptyMessage(0);}

我的存储格式

/** 按时间排序的所有图片list */private ArrayList<SingleImageModel> allImages;/** 按目录排序的所有图片list */private ArrayList<SingleImageDirectories> imageDirectories;/*** 一个文件夹中的图片数据实体*/private class SingleImageDirectories{/** 父目录的路径 */public String directoryPath;/** 目录下的所有图片实体 */public ImageDirectoryModel images;}

一个是全部图片的存储顺序,第二个是按照目录的图片存储顺序

第二步,获取到图片之后,放入到gridview中进行显示,但是BitmapFactory.decodeFile()函数会非常耗时,所以为了使得非常流畅的显示图片,创建一个类AlbumBitmapCacheHelper.class,用来异步加载图片,

该类使用

然后使用ThreadPoolExecutor线程池来处理图片的显示,,线程池大小应该设置适中

做完这两件事情之后就可以用来加载图片了,方法getBitmap用来讲

Bitmap bitmap = getBitmapFromCache(path, width, height);//如果能够从缓存中获取符合要求的图片,则直接回调if (bitmap != null) {} else {//新建线程放入线程池去处理该图片的显示}return bitmap;

如果cache中找不到该图片,则调用BitmapFactory.decodeFile()去加载图片,加载图片不能够直接加载原图,会造成OOM,所以要去处理压缩比

BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(path, options);options.inSampleSize = computeScale(options, width, height);options.inJustDecodeBounds = false;bitmap = BitmapFactory.decodeFile(path, options);//获取之后,放入缓存,以便下次继续使用if (bitmap != null && cache!=null) {cache.put(path, bitmap);}方法computeScale()主要是计算图片最小的压缩比,这样在gridview中的getview方法中去调用AlbumBitmapCacheHelper.class的getBitmap方法即可,但是这样会有很多的问题:一个问题就是图片显示会闪,这主要是由于getview的view的复用,解决方法就是使用settag方法holder.iv_content.setTag(path);将要显示的Imageview的tag设置为需要显示的图片路径,这样在回调的时候使用方法gridView.findViewWithTag(path),找到这个imageview进行显示,闪的问题就解决了第二个问题就是加载速度很慢,拉的速度很快的情况下,图片要很久才会加载出来,特别是很大的图片,比如拍照和截图的照片,解决方法第一方案就是在//优化显示效果if(holder.iv_content.getTag() != null) {String remove = (String) holder.iv_content.getTag();AlbumBitmapCacheHelper.getInstance().removePathFromShowlist(remove);}AlbumBitmapCacheHelper.getInstance().addPathToShowlist(path);这样在线程池中的处理方式就是先查看需要显示的path是否在list中,如果没有在list中,则该线程直接关闭,如果在list中,则显示该图片if (!currentShowString.contains(path)||cache==null) {return;}第二个方案就是如果显示的图片很大,特别是拍照,截图和解图的图片,decode有时会耗时几秒中,微信显示效果非常好,我自己想出来的处理的方式就是***第一步,从应用的缓存temp目录下取,如果取不到,***第二步,计算图片的压缩比例samplesize,如果samplesize < 4,图片的BitmapFactory.decodeFile()时间短,直接返回图片,但是如果 samplesize > 4,执行第三步***第三步则将压缩后的图片存入temp目录下,以便下次快速取出这样显示图片的效果就出来了,显示的速度除了和微信一样第一次大图加载慢之外,之后的显示就能很快了,if (!new File(CommonUtil.getDataPath()).exists())new File(CommonUtil.getDataPath()).mkdirs();//临时文件的文件名String tempPath = CommonUtil.getDataPath() + hash + ".temp";//如果该文件存在if (new File(tempPath).exists())bitmap = BitmapFactory.decodeFile(tempPath);……//第三步,如果缩放比例大于4,该图的加载会非常慢,所以将该图保存到临时目录下以便下次的快速加载if (options.inSampleSize >= 4) {try {File file = new File(tempPath);if (!file.exists())file.createNewFile();FileOutputStream fos = new FileOutputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);fos.write(baos.toByteArray());fos.flush();fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

问题就差不多解决了

第三步大图的查看,大图只要是使用的网上找的ZoomImageView+viewpagger的组合,但是使用这个出现的问题就是很容易OOM,没办法,我的处理方式就是在点进去大图的时候

public void releaseHalfSizeCache() {cache.resize((int) (Runtime.getRuntime().maxMemory() / 1024 / 8));}

直接将cache的大小变成原来的一半,因为查看大图页,加载一张大图占用的内存就很大,这样显示效果页还凑合,有别的方法,一定要留言告诉我

还有不愿面对失败的尴尬。曾经怀有远大理想,拥有完美的憧憬。

android仿最新6.2版本微信相册

相关文章:

你感兴趣的文章:

标签云: