您的位置:首页 > 移动开发 > 微信开发

仿微信选择图片之——加载内存中所有图片

2015-10-08 16:51 513 查看
本文采用了结合LruCache内存缓存方式,LruCache介绍请看:http://blog.csdn.net/guolin_blog/article/details/9316683

第一步:加载硬盘中的图片



Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = context.getContentResolver().query(mImageUri,null,MediaStore.Images.Media.MIME_TYPE+"=? or "+MediaStore.Images.Media.MIME_TYPE+"=?",new String[]{"image/png","image/jpeg"},null);获取到硬盘中的图片地址
②逐一读取并分类

下面贴出整体代码

public class ContentResolvePic {
private static HashMap<String,ArrayList<String>> mGroupMap = null;
public static void getPicMap(final Context context, final GetPicCallback callback){
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
callback.callback(mGroupMap);//如果读取成功回调返回
}
};
if(mGroupMap == null){
new Thread(new Runnable() {
@Override
public void run() {
mGroupMap = new HashMap<String, ArrayList<String>>();
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = context.getContentResolver().query(mImageUri,null,MediaStore.Images.Media.MIME_TYPE+"=? or "+MediaStore.Images.Media.MIME_TYPE+"=?"
,new String[]{"image/png","image/jpeg"},null);
while (cursor.moveToNext()){
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));//这里将各个相册分类
if(!mGroupMap.containsKey("all")){
ArrayList<String> allList = new ArrayList<String>();
mGroupMap.put("all",allList);
}
mGroupMap.get("all").add(0,path);
File pathFile = new File(path);
String parentName = pathFile.getParentFile().getName();
if(!mGroupMap.containsKey(parentName)){
ArrayList<String> list = new ArrayList<String>();
mGroupMap.put(parentName,list);
}
mGroupMap.get(parentName).add(0,path);
}
cursor.close();
handler.sendEmptyMessage(0x123);
}
}).start();
}else {
callback.callback(mGroupMap);
}
}
interface GetPicCallback{
void callback(HashMap<String,ArrayList<String>> hashMap);
}
}这个类封装用来获取硬盘中的图片信息。

第二步:指定缓冲区,帮助我们缓存图片
/**
* Created by rudy on 2015/8/26.
* 这个类用来将图片信息缓存到内存中
*/
public class NativeImageLoader {
//指定线程池
ExecutorService loadImageThreadPool = Executors.newFixedThreadPool(3);
public static LruCache<String,Bitmap> mMemoryCache;//缓存区
private boolean load = true; //指定是否可以加载图片,这里是在滑动的时候可以暂停加载
private NativeImageLoader(){
//指定缓存区的大小
long maxMemory = Runtime.getRuntime().maxMemory()/1024;
final int cacheSize = (int)maxMemory/4;
mMemoryCache = new LruCache<String,Bitmap>(cacheSize){
//计算bitmap的大小
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount()/1024;
}

//            @Override
//            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
//                super.entryRemoved(evicted, key, oldValue, newValue);
//                mMemoryCache.remove(key);
//                oldValue.recycle();
//                oldValue = null;
//            }
};
}
private static NativeImageLoader nativeImageLoader=null;
public static NativeImageLoader getInstance(){
if(null == nativeImageLoader){
synchronized (NativeImageLoader.class){
if(null == nativeImageLoader){
nativeImageLoader =   new NativeImageLoader();
}
}
}
return nativeImageLoader;
}
//方法重载 加载图片通过path
public Bitmap loadNativeImage(String path,ImageLoadCallback callback){
return this.loadNativeImage(path,null,callback);
}
//方法重载 加载图片通过path,并指定缩放倍数
public Bitmap loadNativeImage(final String path, final Point mpoint, final ImageLoadCallback imageLoadCallback){
Bitmap bitmap = null;
if(load){
bitmap = getBitmapFromMemoryCache(path);

final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
imageLoadCallback.callback(path, (Bitmap) msg.obj);
}
};
if(bitmap ==null){
loadImageThreadPool.execute(new Runnable() {
@Override
public void run() {
Bitmap bitmap;
//                        bitmap = decodeSampledBitmapFromPath(path, mpoint == null ? 0 : mpoint.x, mpoint == null?0:mpoint.y);
bitmap = ImageUtil.getBitmapFromPathWithRequest(path, mpoint == null ? 0 : mpoint.x, mpoint == null?0:mpoint.y);
Message msg = handler.obtainMessage();
msg.obj = bitmap;
addBitmapToMemoryCache(path,bitmap);
handler.sendMessage(msg);
}
});
}
}
return  bitmap;
}
public static void addBitmapToMemoryCache(String path,Bitmap bitmap){
if(getBitmapFromMemoryCache(path)==null&&bitmap!=null){
synchronized (mMemoryCache) {
mMemoryCache.put(path, bitmap);
}
}
}
public static Bitmap getBitmapFromMemoryCache(String path){
synchronized (mMemoryCache) {
return mMemoryCache.get(path);
}
}
public interface ImageLoadCallback{
void callback(String path, Bitmap bitmap);
}
public void stopLoadImage(boolean load){
this.load = load;
}
}


上面的ImageUtil类,是一个自己封装的图片工具类 用来放大或缩小我们的Bitmap,合理运用内存
/**
* Created by rudy on 2015/9/2.
*这个类是为了计算Bitmap的缩放而获得缩放后的Bitmap
*/
public class ImageUtil {
private static ImageUtil imageUtil = null;
private static ImageUtil getInstance(){
if(null == imageUtil){
synchronized (ImageUtil.class){
if(null == imageUtil){
imageUtil = new ImageUtil();
}
}
}
return imageUtil;
}
private int calculateInSampleSize(BitmapFactory.Options options,int reqHeight,int reqWidth){
int sampleSize = 1;
int picHeight = options.outHeight;
int picWidth = options.outWidth;
return calculateInSampleSize(reqHeight, reqWidth, sampleSize, picHeight, picWidth);
}
//计算缩放倍数
private int calculateInSampleSize(int reqHeight, int reqWidth, int sampleSize, int picHeight, int picWidth) {
if(picHeight>reqHeight && picWidth>reqWidth){
sampleSize = picHeight>picWidth?picWidth/reqWidth:picHeight/reqHeight;
}
return sampleSize;
}

//加载Bitmap
private Bitmap decodeSampledBitmapFromPath(String path,int reqHeight,int reqWidth){
Bitmap bitmap = null;
BitmapFactory.Options options =new BitmapFactory.Options();
if(reqHeight!=0&&reqWidth!=0){
options.inJustDecodeBounds = true;//这是表示不分配内存的
BitmapFactory.decodeFile(path,options);
options.inSampleSize = calculateInSampleSize(options,reqHeight,reqWidth);
options.inJustDecodeBounds = false;
}
bitmap = BitmapFactory.decodeFile(path,options);
return bitmap;
}
private Bitmap decodeSampledBitmapFromByte(byte[] bytes,int reqHeight,int reqWidth){
Bitmap bitmap = null;
BitmapFactory.Options options =new BitmapFactory.Options();
if(reqHeight!=0&&reqWidth!=0){
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
options.inSampleSize = calculateInSampleSize(options,reqHeight,reqWidth);
options.inJustDecodeBounds = false;
}
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
return bitmap;
}
public static Bitmap getBitmapFromPathWithRequest(String path,int reqHeight,int reqWidth){
return getInstance().decodeSampledBitmapFromPath(path,reqHeight,reqHeight);
}
}

所需要的工具类已经写好,下一步就是进行显示。也就是制定适配器
贴一下代码:

/**
* Created by rudy on 2015/8/26.
*/
public class GalleryAdapter extends BaseAdapter implements AbsListView.OnScrollListener {
private Context context;
private Point mpoint = new Point(160,160);
private GridView gallery;
private ArrayList<String> list;
private LayoutInflater inflater;
// private NativeImageLoader imageLoader;
private int firstItem,visibleItem;
private HashMap<Integer,Boolean> mSelectItem = new HashMap<Integer,Boolean>();
public GalleryAdapter(Context context,ArrayList<String> list,GridView gallery){
inflater = LayoutInflater.from(context);
this.context = context;
this.list = list;
this.gallery = gallery;
// imageLoader = NativeImageLoader.getInstance();
gallery.setOnScrollListener(this);
}
@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return position;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
String path = list.get(position);
MyImageView imageView=null;
ViewHolder viewHolder = null;
if(convertView == null){
convertView = inflater.inflate(R.layout.content_layout,null);
viewHolder = new ViewHolder();
viewHolder.imageView = (MyImageView)convertView.findViewById(R.id.image);
viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkbox);
viewHolder.chooseView =(MyImageView) convertView.findViewById(R.id.choose_pic);
convertView.setTag(viewHolder);
viewHolder.imageView.setOnMeasureListener(new MyImageView.OnMeasureListener() {
@Override
public void onMeasureSize(int width, int height) {
mpoint.set(width/2,height/2);
}
});
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
imageView = viewHolder.imageView;
final View chooseView = viewHolder.chooseView;
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSelectItem.put(position,isChecked);
chooseView.setSelected(isChecked);
}
});
viewHolder.checkBox.setChecked(mSelectItem.containsKey(position) ? mSelectItem.get(position) : false);
chooseView.setSelected(mSelectItem.containsKey(position)?mSelectItem.get(position):false);
imageView.setTag(path);
setBitMap(path,imageView);
return convertView;
}
private void setBitMap(String path,ImageView imageView){
Bitmap bitmap = NativeImageLoader.getInstance().loadNativeImage(path, mpoint, new NativeImageLoader.ImageLoadCallback() {
@Override
public void callback(String path, Bitmap bitmap) {
MyImageView imageView1 = (MyImageView) gallery.findViewWithTag(path);
if (imageView1 != null && path != null && bitmap != null) {
imageView1.setImageBitmap(bitmap);
}
}
});
if(bitmap == null){
imageView.setImageResource(R.mipmap.pic);
}else {
imageView.setImageBitmap(bitmap);
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
NativeImageLoader.getInstance().stopLoadImage(true);
for (int i = firstItem;i<firstItem+visibleItem;i++){
setBitMap(list.get(i),(ImageView) gallery.findViewWithTag(list.get(i)));
}
}
if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING){
NativeImageLoader.getInstance().stopLoadImage(false);
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem!=0){
// imageLoader.stopLoadImage(false);
}
firstItem = firstVisibleItem;
visibleItem = visibleItemCount;
}

class ViewHolder{
public CheckBox checkBox;
public MyImageView imageView;
public MyImageView chooseView;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: