图片加载器:
1 最重要的为ImageLoader类 :
/**
* 保证了图片压缩,缓存和正常加载
* @author micro
*
*/
public class ImageLoader {
/**
* 图片缓存空间
*/
private LruCache<String, Bitmap> mLruCache;
//线程池
private ExecutorService mThreadPools;
private static final int DEFAULT_THREAD_COUNT = 1;
/**
* 队列的调度方式,也就是图片的显示方式
*/
private Type mType = Type.LIFO;
/**
* Runnable任务队列
*/
private LinkedList<Runnable> mTaskQuene;
/**
* 轮询线程hanlder+Looper+Message
*/
private Thread mPoolThread;
private Handler mPoolThreadHandler;
/**
* UI处理线程
*/
private Handler mUIHandler;
/**
* 图片显示的方法
* LIFO拉到哪里,哪里就显示
* FIFO表示从第一张开始显示
*/
public enum Type{
LIFO,FIFO
}
//信号量,防止并发的类,保证Handler不为NUll
/* a semaphore maintains a set of permits.
* Each acquire() blocks if necessary until a permit is available,
* and then takes it. Each release() adds a permit,
* potentially releasing a blocking acquirer.
* However, no actual permit objects are used;
* the Semaphore just keeps a count of the number available
* and acts accordingly. */
private Semaphore mSemaphorePoolTreadHandler = new Semaphore(0);
//保证线程池的正常执行和运行
private Semaphore mSemaphoreThreadPool ;
private static ImageLoader imageLoaderInstance;
//ImageLoader
private ImageLoader(int threadCount,Type type){
init(threadCount,type);
}
/**
* 初始化变量
* @param threadCount
* @param type
*/
private void init(int threadCount, Type type) {
// TODO Auto-generated method stub
//
mPoolThread = new Thread(){
@Override
public void run() {
Looper.prepare();
mPoolThreadHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
//线程池取出一个任务执行
mThreadPools.execute(getTask());
try {
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
}
};
//release一个信号量
mSemaphorePoolTreadHandler.release();
Looper.loop();
}
};
//开启线程
mPoolThread.start();
//初始化缓存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheMemory = maxMemory/8;
mLruCache = new LruCache<String, Bitmap>(cacheMemory){
@Override
protected int sizeOf(String key, Bitmap value) {
//测量每一个Bitmap的大小
// TODO Auto-generated method stub
return value.getRowBytes()*value.getHeight();
//字节数*高度
}
};
//创建线程池
mThreadPools = Executors.newFixedThreadPool(threadCount);
mTaskQuene = new LinkedList<Runnable>();
mType = type;
//初始化
mSemaphoreThreadPool = new Semaphore(threadCount);
}
//单例模式
//这样判断的好处就是使得效率提高
public static ImageLoader getInstance(int threadCount,Type type){
if(imageLoaderInstance==null){
synchronized (ImageLoader.class) {
if(imageLoaderInstance==null){
//这里开启了轮询线程
imageLoaderInstance = new ImageLoader(threadCount,type);
}
}
}
return imageLoaderInstance;
}
/**
* 加载图片
* @param path
* @param imageView
*/
public void loadImage(final String path,final ImageView imageView){
imageView.setTag(path);
if(mUIHandler==null){
mUIHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
//获取图片,为ImageView回调设置图片
//获取资源
ImageBeanHolder holder = (ImageBeanHolder) msg.obj;
String path = holder.path;
Bitmap bm = holder.bm;
ImageView imageView = holder.imageView;
//判断path与getTag存储路径进行比较,一致则显示出来
if(imageView.getTag().toString().equals(path)){
imageView.setImageBitmap(bm);
}
}
};
}
//在缓存中获取对应路径的图片
Bitmap bm = getBitmapFromLrucache(path);
//找到就
if(bm!=null){
//回调
Message message = Message.obtain();
//ImageBeanHoler避免错乱
ImageBeanHolder holder = new ImageBeanHolder();
holder.bm = bm;
holder.path = path;
holder.imageView = imageView;
message.obj=holder;
mUIHandler.sendMessage(message);
//执行完毕之后再到UI线程做进一步处理
}else{
//找不到就添加任务到线程处理
//addTasK里也发送到轮询线程处理
addTask(new Runnable() {
public void run() {
//加载图片
//1 获取图片的大小
ImageSize imageSize = getImageSize(imageView);
//2进行压缩
Bitmap bm = decodeSampledBitmapFromPath(path,imageSize.width,imageSize.height);
//3图片加载到缓存
addBitmaptoLrucache(path,bm);
//4回调
Message message = Message.obtain();
ImageBeanHolder holder = new ImageBeanHolder();
holder.bm = bm;
holder.path = path;
holder.imageView = imageView;
message.obj=holder;
mUIHandler.sendMessage(message);
mSemaphoreThreadPool.release();
}
});
}
}
/**
* 添加图片到缓存
* @param path
* @param bm
*/
protected void addBitmaptoLrucache(String path, Bitmap bm) {
// TODO Auto-generated method stub
if(getBitmapFromLrucache(path)==null){
if(bm!=null){
mLruCache.put(path, bm);
}
}
}
/**
* 图片压缩
* @param path
* @param width
* @param height
* @return
*/
protected Bitmap decodeSampledBitmapFromPath(String path,
int width, int height) {
// TODO Auto-generated method stub
//获取图片的宽和高,并不把图片加载到内存中
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
//比较图片与options的宽和高
options.inSampleSize = calculateInSampleSize(options,width,height);
//获取InSampleSize再次解析图片
options.inJustDecodeBounds =false;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
return bitmap;
}
/**
* 根据需求和实际的宽和高计算inSampleSize
* @param options
* @param width
* @param height
* @return
*/
private int calculateInSampleSize(Options options, int reqwidth, int reqheight) {
// TODO Auto-generated method stub
int width = options.outWidth;
int height = options.outHeight;
int inSampleSize =1 ;
if(width>reqwidth || height>reqheight){
int widthRadio = Math.round(width*1.0f/reqwidth);
int heightRadio = Math.round(height*1.0f/reqheight);
inSampleSize = Math.max(widthRadio, heightRadio);
}
return inSampleSize;
}
/**
* 获取图片的大小
* @param imageView
* @return
*/
protected ImageSize getImageSize(ImageView imageView) {
ImageSize imageSize = new ImageSize();
LayoutParams lp = imageView.getLayoutParams();
//获取屏幕的参数
DisplayMetrics displayMetrics =
imageView.getContext().getResources().getDisplayMetrics();
int width = imageView.getWidth();//获取实际宽度
// int width = getImageViewFieldValue(imageView, "mMaxWidth");
//
if(width<=0){
width = lp.width;//获取imageView在Layout中声明的宽度
}
if(width<=0){
width = getImageViewFieldValue(imageView, "mMaxWidth"); //检查最大值
}
//最坏的情况下等于屏幕宽度
if(width<=0){
width = displayMetrics.widthPixels;
}
int height = imageView.getHeight();
// int height = getImageViewFieldValue(imageView, "mMaxHeight");//获取实际高度
if(height<=0){
height = lp.height;//获取imageView在Layout中声明的高度
}
if(height<=0){
height = getImageViewFieldValue(imageView, "mMaxHeight"); //发射获取检查最大值,避免了仅Api16可用的
}
//最坏的情况下等于屏幕高度
if(height<=0){
height = displayMetrics.heightPixels;
}
//
imageSize.width = width;
imageSize.height = height;
return imageSize;
// TODO Auto-generated method stub
}
/**
* 通过反射获取ImageView的任意属性值
* @param object
* @param filedName
* @return
*/
private static int getImageViewFieldValue(Object object,String filedName){
int value = 0;
try {
Field field = ImageView.class.getDeclaredField(filedName);
field.setAccessible(true);
int fieldValue = field.getInt(object);//获取字段值
if(fieldValue>0 && fieldValue<Integer.MAX_VALUE){
value = fieldValue;
}
} catch (Exception e) {
// TODO: handle exception
}
return value;
}
private class ImageSize{
int width;
int height;
}
/**
* 从任务队列取出一个任务
* @return
*/
private Runnable getTask() {
// TODO Auto-generated method stub
if(mType==Type.FIFO){
return mTaskQuene.removeFirst();
}else if(mType==Type.LIFO){
return mTaskQuene.removeLast();
}
return null;
}
/**
* 找不到就添加任务到线程处理
* @param runnable
*/
private synchronized void addTask(Runnable runnable) {
// TODO Auto-generated method stub
mTaskQuene.add(runnable);
//防止并发
try {
if(mPoolThreadHandler==null){
mSemaphorePoolTreadHandler.acquire();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//发送到轮询线程Handler处理
mPoolThreadHandler.sendEmptyMessage(0X110);
}
private Bitmap getBitmapFromLrucache(String path) {
// TODO Auto-generated method stub
return mLruCache.get(path);
}
private class ImageBeanHolder{
Bitmap bm;
String path;
ImageView imageView;
}
}
2 GridView的适配器
ViewHolder:
/**
* 这里ViewHolder实现了对各个View的设置
* 以及mConvertView的优化
* @author micro
*
*/
public class ViewHolder {
/*SparseArray:
* It is intended to be more memory efficient
* than using a HashMap to map Integers to Objects, both because it avoids
* auto-boxing keys and its data structure doesn‘t rely on an extra entry object
* for each mapping.*/
private SparseArray<View> mViews; //View集合,高效
private int mPostion; //position
private View mConvertView; //传入的View
private ViewHolder(Context context,ViewGroup parent,int layoutId,
int position){
this.mPostion = position;
this.mViews = new SparseArray<View>();
this.mConvertView = LayoutInflater.
from(context).inflate(layoutId,parent,false);
mConvertView.setTag(this);
}
//获取ViewHolder
public static ViewHolder get(Context context,View convertView,
ViewGroup parent,int layoutId,int position){
ViewHolder holder = null;
if(convertView==null){
holder = new ViewHolder(context, parent, layoutId, position);
}else{
holder = (ViewHolder)convertView.getTag();
holder.mPostion = position;
}
return holder;
}
public View getConvertView(){
return mConvertView;
}
/**
* 通过资源iD获取View控件,如果为空,则加入mViews中
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId){
View view = mViews.get(viewId);
if(view==null){
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
/**
* 给TextView赋值字符串
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId,String text){
TextView textView = getView(viewId);
textView.setText(text);
return this;
}
/**
* 资源id设置ImageView
* @param viewId
* @param drawableId
* @return
*/
public ViewHolder setImagetResource(int viewId,int drawableId){
ImageView view = getView(viewId);
view.setImageResource(drawableId);
return this;
}
/**
* bitmap设置ImageView
* @param viewId
* @param bitmap
* @return
*/
public ViewHolder setImageBitmap(int viewId,Bitmap bitmap){
ImageView view =getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
/**
* url设置ImageView
* @param viewId
* @param url
* @return
*/
public ViewHolder setImageByUrl(int viewId,String url){
ImageLoader.getInstance(3, Type.LIFO).
loadImage(url, (ImageView)getView(viewId));
return this;
}
public int getPosition(){
return mPostion;
}
}
public abstract class CommonAdapter<T> extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected int mItemLayoutId;
//构造器对上面的变量初始化
public CommonAdapter(Context context,List<T> datas,int ItemlayoutId){
this.mContext = context;
this.mDatas = datas;
this.mItemLayoutId = ItemlayoutId;
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mDatas.size();
}
@Override
public T getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder viewHolder = getViewHolder(position, convertView, parent);
convert(viewHolder, getItem(position));
return viewHolder.getConvertView();
}
//抽象方法
public abstract void convert(ViewHolder holder,T item);
private ViewHolder getViewHolder(int position, View convertView, ViewGroup parent){
return ViewHolder.
get(mContext, convertView, parent, mItemLayoutId, position);
}
}
/**
* GridView的最终适配器
* @author micro
*
* @param <T>
*/
public class MyAdapter extends CommonAdapter<String> {
//这个存储的就是图片的路径集合
public static List<String> mSelectImage = new
LinkedList<String>();
//文件夹路径
private String mDirPath;
/**
* 构造器初始化
* @param context
* @param datas
* @param ItemlayoutId
*/
public MyAdapter(Context context, List<String> datas, int ItemlayoutId
,String dirPath) {
super(context, datas, ItemlayoutId);
// TODO Auto-generated constructor stub
mDirPath = dirPath;
}
/**
* 通过重写这个方法来设置不同点击状态下的变化
*/
@Override
public void convert(final ViewHolder holder, final String item) {
// TODO Auto-generated method stub
//no pic
holder.setImagetResource(R.id.id_item_image, R.drawable.pictures_no);
//no selected
holder.setImagetResource(R.id.id_item_image, R.drawable.pictures_selected);
//设置图片
holder.setImageByUrl(R.id.id_item_image, mDirPath+"/"+item);
//获取两个控件,下面将进行设置
final ImageView mImageView = holder.getView(R.id.id_item_image);
final ImageView mSelect = holder.getView(R.id.id_item_select);
mImageView.setColorFilter(null);
mImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//已经选择的图片
if(mSelectImage.contains(mDirPath+"/"+item)){
mSelectImage.remove(mDirPath+"/"+item);
mSelect.setImageResource(R.drawable.picture_unselected);
mImageView.setColorFilter(null);
}else{
//没有选择,则
mSelectImage.add(mDirPath+"/"+item);
mSelect.setImageResource(R.drawable.pictures_selected);
mImageView.setColorFilter(Color.parseColor("#77000000"));
}
}
});
/**
* 已经选择过的图片,显示出选择过的效果
*/
if(mSelectImage.contains(mDirPath + "/" + item)){
mSelect.setImageResource(R.drawable.pictures_selected);
mImageView.setColorFilter(Color.parseColor("#77000000"));
}
}
}
3 popWindow的使用
/**
* 这个相当于一个Activity,不过这个是显示在一个Activity之上的
* 这里的BasePopupWindowForListView只是提供了一个模板供子类继承其功能
* 子类最终将完善其功能
* @author micro
* @param <T>
*
*/
public abstract class BasePopupWindowForListView<T> extends PopupWindow {
/**
* 布局文件的最外层的View
*/
protected View mContentView;
protected Context mContext;
//数据
protected List<T> mDatas;
//构造器
public BasePopupWindowForListView(View contentView,int width,int height,
boolean focusable){
this(contentView, width, height, focusable, null);
}
public BasePopupWindowForListView(View contentView,int width,int height,
boolean focusable,List<T> mDatas){
this(contentView, width, height, focusable,mDatas,new Object[0]);
}
public BasePopupWindowForListView(View contentView,int width,int height,
boolean focusable,List<T> mDatas,Object... params){
super(contentView, width, height, focusable);
this.mContentView = contentView;
mContext = contentView.getContext();
if(mDatas!=null){
this.mDatas = mDatas;
}
if(params!=null && params.length>0){
beforeInitWeNeedSomeParams(params);
}
//popWindow一些属性设置
setBackgroundDrawable(new BitmapDrawable());
/* When touchable,
* the window will receive touch events,
* otherwise touch events will go to the
* window below it. By default the window is touchable.*/
setTouchable(true);//这个很重要
setOutsideTouchable(true);
setTouchInterceptor(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
dismiss();
return true;
}
return false;
}
});
initViews();
initEvent();
inits();
}
protected abstract void beforeInitWeNeedSomeParams(Object[] params);
protected abstract void initViews();
protected abstract void initEvent();
protected abstract void inits();
public View findViewById(int id){
return mContentView.findViewById(id);
}
/**
* dp -->px转化
* @param context
* @param dp
* @return
*/
protected static int dpToPx(Context context,int dp){
return (int) (context.getResources().getDisplayMetrics().densityDpi*dp +0.5f);
}
}
public class ListImageDirPopupWindow extends BasePopupWindowForListView<ImageFolder> {
private ListView mListDir;
public ListImageDirPopupWindow(View convertView, int width, int height,
List<ImageFolder> datas) {
super(convertView, width, height, true,datas);
}
@Override
protected void beforeInitWeNeedSomeParams(Object[] params) {
// TODO Auto-generated method stub
}
@Override
protected void initViews() {
// TODO Auto-generated method stub
mListDir = (ListView)findViewById(R.id.id_list_dir);
mListDir.setAdapter(new CommonAdapter<ImageFolder>(mContext,mDatas,
R.layout.list_dir_item) {
@Override
public void convert(ViewHolder holder, ImageFolder item) {
// TODO Auto-generated method stub
holder.setText(R.id.id_dir_item_name, item.getName());
holder.setImageByUrl(R.id.id_dir_item_img,item.getFirstImagePath());
holder.setText(R.id.id_dir_item_count, item.getCount()+"张");
}
});
}
/**
* 图片文件夹选中监听接口
* @author micro
*
*/
public interface OnImageDirSelected{
void selected(ImageFolder folder);
}
public OnImageDirSelected onImageDirSelected;
public void setOnImageDirSelected(OnImageDirSelected mOnImageDirSelected){
this.onImageDirSelected = mOnImageDirSelected;
}
@Override
protected void initEvent() {
// TODO Auto-generated method stub
//ListView的点击监听中调用了onImageDirSelected
mListDir.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
if(onImageDirSelected!=null){
onImageDirSelected.selected(mDatas.get(position));
}
}
});
}
@Override
protected void inits() {
// TODO Auto-generated method stub
}
}
4 一些常用的方法
获取屏幕的高度:
private int mScreenHeight; //屏幕高度
//获取屏幕高度的方法
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
mScreenHeight = outMetrics.heightPixels;
设置一些背景变暗:
//设置背景变暗
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
getWindow().setAttributes(lp);
内容提供器:
Uri imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//获取一个内容提供器
ContentResolver mContentResolver = MainActivity.this.getContentResolver();
//查询
Cursor cursor = mContentResolver.query(imageUri, null,
MediaStore.Images.Media.MIME_TYPE+"=? or "
+MediaStore.Images.Media.MIME_TYPE+"=?",
new String[]{"image/jpeg","image/png"},
MediaStore.Images.Media.DATE_MODIFIED);
5 最后的MainActivity:
public class MainActivity extends Activity {
private ProgressDialog mProgressDialog;
private int mPicsSize; //图片数量
private File mImgDir; //图片数量最多的文件夹,将图片最多的文件夹显示
private List<String> mImgs; //文件夹下的所有图片
private GridView mGridView;
private MyAdapter mMyaAdapter;
//临时的辅助类,防止同一文件夹的多次扫描
private HashSet<String> mDirpaths = new HashSet<String>();
//扫描拿到的所有图片的文件夹
private List<ImageFolder> mImageFolders = new ArrayList<ImageFolder>();
private RelativeLayout mBottomly;
private TextView mChooseDir;
private TextView mImageCount;
int totalCount = 0;
private int mScreenHeight; //屏幕高度
private ListImageDirPopupWindow mListImageDirPopupWindow;
//通知Handler扫描图片已完成,然后处理并初始化PopupWindw
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
mProgressDialog.dismiss();
data2View();//最终将文件夹中图片最多的文件夹下的图片显示在一开始的主界面中
initListDirPopupWindw();
}
};
/**
* 为View绑定数据
*/
private void data2View() {
// TODO Auto-generated method stub
if( mImgDir==null ){
Toast.makeText(getApplicationContext(), "您的手机没有图片",Toast.LENGTH_SHORT).show();
return ;
}
mImgs = Arrays.asList(mImgDir.list()); //获取文件夹的所有图片文件
mMyaAdapter = new MyAdapter(
getApplicationContext(), mImgs,
R.layout.grid_item, mImgDir.getAbsolutePath());
mGridView.setAdapter(mMyaAdapter);
mImageCount.setText(totalCount+"张");
};
/**
* 初始化PopWindow
*/
private void initListDirPopupWindw() {
// TODO Auto-generated method stub
//加载布局
mListImageDirPopupWindow = new ListImageDirPopupWindow(LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_dir, null),
LayoutParams.MATCH_PARENT, (int) (mScreenHeight*0.7), mImageFolders);
//
mListImageDirPopupWindow.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
// TODO Auto-generated method stub
//设置背景变暗
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
getWindow().setAttributes(lp);
}
});
// 设置选择文件夹的回调,点击监听,显示
mListImageDirPopupWindow.setOnImageDirSelected(new OnImageDirSelected() {
@Override
public void selected(ImageFolder folder) {
// TODO Auto-generated method stub
mImgDir = new File(folder.getDir());
//文件处理和过滤器
mImgs = Arrays.asList(mImgDir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if(filename.endsWith(".jpg")||filename.endsWith(".png")||filename.endsWith(".jpeg")
||filename.endsWith(".JPG") || filename.endsWith(".PNG")||
filename.endsWith(".JPEG")){
return true;
}
return false;
}
}));
//将图片显示出来
mMyaAdapter = new MyAdapter(
getApplicationContext(), mImgs,
R.layout.grid_item, mImgDir.getAbsolutePath());
mGridView.setAdapter(mMyaAdapter);
mImageCount.setText(folder.getCount()+"张");
mChooseDir.setText(folder.getName());
mListImageDirPopupWindow.dismiss();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//获取屏幕高度的方法
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
mScreenHeight = outMetrics.heightPixels;
//初始化
initViews();
getImages();
initEvent();
}
/**
* 初始化事件
*/
private void initEvent() {
// TODO Auto-generated method stub
mBottomly.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//这里设置了一个淡出动画
mListImageDirPopupWindow.
setAnimationStyle(R.style.anim_popup_dir);
//从底部弹出
mListImageDirPopupWindow.showAsDropDown(mBottomly,0,0);
//设置背景
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = .3f;
getWindow().setAttributes(lp);
}
});
}
/**
* 获取图片
*/
private void getImages() {
// TODO Auto-generated method stub
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Toast.makeText(getApplicationContext(), "暂无外置存储", Toast.LENGTH_SHORT).show();
}
//显示进度Dialog
mProgressDialog = ProgressDialog.show(this,null , "正在加载...");
//运行在子线程中 完成图片的扫描,最终获得jpg最多的那个文件夹
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String firstPath =null;
Uri imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//获取一个内容提供器
ContentResolver mContentResolver = MainActivity.this.getContentResolver();
//查询
Cursor cursor = mContentResolver.query(imageUri, null,
MediaStore.Images.Media.MIME_TYPE+"=? or "
+MediaStore.Images.Media.MIME_TYPE+"=?",
new String[]{"image/jpeg","image/png"},
MediaStore.Images.Media.DATE_MODIFIED);
while(cursor.moveToNext()){
//获取图片路径
String path = cursor.getString(
cursor.getColumnIndex(MediaStore.Images.Media.DATA));
//拿到第一张图片的路径
if(firstPath==null){
firstPath = path;
Log.e("firstPath", "firstPath");
}
//获取该图片的父路径
File parentFile = new File(path).getParentFile();
if(parentFile==null){
continue;
}
String dirPath = parentFile.getAbsolutePath();
ImageFolder imageFolder =null;
// 利用一个HashSet防止多次扫描同一个文件夹
if(mDirpaths.contains(dirPath)){
continue;
}else{
mDirpaths.add(dirPath);
imageFolder = new ImageFolder();
imageFolder.setDir(dirPath);
imageFolder.setFirstImagePath(path);
}
int picSize = parentFile.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
if(filename.endsWith(".png")
|| filename.endsWith(".jpg")
|| filename.endsWith(".jpeg")
|| filename.endsWith(".JPG")
|| filename.endsWith(".PNG")
|| filename.endsWith(".JPEG")){
return true;
}
return false;
}
}).length;
totalCount+=picSize;
imageFolder.setCount(picSize);
mImageFolders.add(imageFolder);
//获取了最多图片的文件夹
if(picSize>mPicsSize){
mPicsSize = picSize;
mImgDir = parentFile;
}
}
cursor.close();
// 扫描完成,辅助的HashSet也就可以释放内存了
mDirpaths = null;
// 通知Handler扫描图片完成
mHandler.sendEmptyMessage(0X110);
}
}).start();
}
private void initViews() {
mGridView = (GridView)findViewById(R.id.id_gridview);
mChooseDir = (TextView)findViewById(R.id.id_choose_dir);
mImageCount = (TextView)findViewById(R.id.id_total_count);
mBottomly = (RelativeLayout)findViewById(R.id.id_bottom_ly);
}
}
6 效果显示:
7 感谢http://blog.csdn.net/lmj623565791/article/details/39943731所提供的参考
时间: 2024-10-25 04:31:30