仿微信选择图片之——加载内存中所有图片
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);
}
}这个类封装用来获取硬盘中的图片信息。
第二步:指定缓冲区,帮助我们缓存图片
上面的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;
}
}
第一步:加载硬盘中的图片
①
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;
}
}
相关文章推荐
- 微信公众号的开发
- 微信自定义菜单说php json_encode不转义中文汉字的方法
- qt入门小程序
- iOS 支付 [支付宝、银联、微信]
- Android:布局实例之模仿微信Tab
- iOS 支付 [支付宝、银联、微信](转载)
- 微信扫码支付--xml解析
- Android模仿微信语音聊天功能-IT蓝豹
- 微信本地开发环境设定
- IOS 微信支付
- Android:仿微信开场切换界面
- JDBC--最简单的java连接数据库的小程序
- 小程序
- Android 高仿微信即时聊天 百度云为基础的推
- android 仿微信雷达扫描
- 微信网页开发问题汇总
- Android QQ、微信聊天消息界面设计原理与实现
- 谈谈:关于敏捷规划的微信对话
- 这是安卓手机打开摄像头的一个小程序
- 李莫愁:耐得住寂寞才能守得住繁华(转自微信)