Android之微信图片加载

来源:互联网 发布:mac dmg 安装 编辑:程序博客网 时间:2024/05/16 18:37

MainActivity

import java.io.File;import java.io.FilenameFilter;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Set;import com.example.imageloader.bean.ImageAdapter;import com.example.imageloader.utils.ImageLoader;import com.example.imageloader.utils.ImageLoader.Type;import com.example.imageloader.utils.ImagePopupWindow;import com.example.imageloader.utils.ImagePopupWindow.OnSelectedListener;import android.app.Activity;import android.app.ProgressDialog;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.provider.MediaStore;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.PopupWindow.OnDismissListener;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {    private GridView mGridView;    private List<String> mLists;    private ImageAdapter mImgAdapter;    private RelativeLayout mBottomLy;    private TextView mDirName;    private TextView mDirCount;    private File mCurrentDir;    private int mMaxcount;    private ProgressDialog mPd;    private List<FolderBean> mFolderBeans = new ArrayList<FolderBean>();    private ImagePopupWindow mPopupWindow;    private Handler handler=new Handler(){        public void handleMessage(android.os.Message msg) {            if(msg.what== 0x110){                mPd.dismiss();                data2View();//绑定数据到view中;                initPopupWindow();            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initDatas();        initEvent();    }    protected void initPopupWindow() {        mPopupWindow=new ImagePopupWindow(this, mFolderBeans);        mPopupWindow.setOnDismissListener(new OnDismissListener() {            @Override            public void onDismiss() {                ligthOn();            }        });        //接口回调         mPopupWindow.setPopSelected(new OnSelectedListener() {            @Override            public void onSelected(FolderBean folderBean) {                // TODO Auto-generated method stub                mCurrentDir=new File(folderBean.getDir());            mLists=Arrays.asList(   mCurrentDir.list(new FilenameFilter() {                    @Override                    public boolean accept(File dir, String filename) {                        if(filename.endsWith(".jpg")||filename.endsWith(".jpeg")||filename.endsWith(".png")  ){                            return true;                        }                        return false;                    }                }));            mImgAdapter=new ImageAdapter(MainActivity.this, mLists, mCurrentDir.getAbsolutePath());            mGridView.setAdapter(mImgAdapter);            mDirCount.setText(mLists.size()+"");            mDirName.setText(folderBean.getName());            mPopupWindow.dismiss();            }        });    }/** * 内容区域变亮 */    protected void ligthOn() {        WindowManager.LayoutParams lp=getWindow().getAttributes();        lp.alpha=1.0f;        getWindow().setAttributes(lp);    }    protected void data2View() {        if(mCurrentDir==null){            Toast.makeText(this, "未扫描到任何图片", Toast.LENGTH_SHORT).show();            return;        }        mLists=Arrays.asList(mCurrentDir.list());        mImgAdapter=new ImageAdapter(this, mLists, mCurrentDir.getAbsolutePath());        mGridView.setAdapter(mImgAdapter);        mDirCount.setText(mMaxcount+"");        mDirName.setText(mCurrentDir.getName());    }    private void initView() {        mGridView = (GridView) findViewById(R.id.gridView);        mBottomLy = (RelativeLayout) findViewById(R.id.rl_bottom);        mDirName = (TextView) findViewById(R.id.id_dir_name);        mDirCount = (TextView) findViewById(R.id.id_dir_count);    }    // ContentProvite扫描手机中所有图片;    private void initDatas() {        if (!(Environment.getExternalStorageState().equals(                Environment.MEDIA_MOUNTED))) {            Toast.makeText(this, "SD卡不可用", Toast.LENGTH_SHORT).show();            return;        }        mPd = ProgressDialog.show(this, null, "正在加载...");        new Thread() {            public void run() {                Uri mImgUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;//获取媒体库图片库uri                ContentResolver cr = MainActivity.this.getContentResolver();                //------------------这里的 + "= ? or " +要注意,格式要对                Cursor cursor=cr.query(mImgUri, null, MediaStore.Images.Media.MIME_TYPE                        + "= ? or " + MediaStore.Images.Media.MIME_TYPE                         + "= ? ",new String[] { "image/jpeg", "image/png" },                        MediaStore.Images.Media.DATE_MODIFIED);                Set<String> mDirPaths=new HashSet<String>();//储存遍历过的防止重复遍历                while(cursor.moveToNext()){                    String path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));//获取每张图片的路径                    File parentFile=new File(path).getParentFile();//获取图片的父文件夹                    if(parentFile==null){                        continue;//结束本次循环,进行下一次循环                    }                    String dirPath=parentFile.getAbsolutePath();//获取此文件夹路径;                    FolderBean folderBean=null;                    //如果包含某个元素                    if(mDirPaths.contains(dirPath)){                        continue;//如果包含,结束循环                    }else{                        mDirPaths.add(dirPath);                        folderBean=new FolderBean();                        folderBean.setDir(dirPath);                        folderBean.setFirstImagePath(path);                                                                 }                    if(parentFile.list()==null){                        continue;                    }                    //获取文件夹中图片数目,有删选                    int picSize=parentFile.list(new FilenameFilter() {                        @Override                        public boolean accept(File dir, String filename) {                            if(filename.endsWith(".jpg")||filename.endsWith(".jpeg")||filename.endsWith(".png")  ){                                return true;                            }                            return false;                        }                    }).length;                    folderBean.setCount(picSize);                    mFolderBeans.add(folderBean);                    //当前文件夹的名称数量。应该扫描一次加一张                    if(picSize>mMaxcount){                        mMaxcount=picSize;                        mCurrentDir=parentFile;                    }                }                cursor.close();                //通知handler扫描图片完成                handler.sendEmptyMessage(0x110);            };        }.start();    }    private void initEvent() {      mBottomLy.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            //mPopupWindow.setAnimationStyle(animationStyle);            mPopupWindow.showAsDropDown(mBottomLy, 0, 0);            lightOff();        }    });    }    protected void lightOff() {        WindowManager.LayoutParams lp=getWindow().getAttributes();        lp.alpha=0.3f;        getWindow().setAttributes(lp);    }}

ImagePopupWindow

import java.util.List;import com.example.imageloader.FolderBean;import com.example.imageloader.R;import com.example.imageloader.utils.ImageLoader.Type;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.View.OnTouchListener;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.PopupWindow;import android.widget.TextView;public class ImagePopupWindow extends PopupWindow {    private int mWidth;    private int mHeight;    private View mConvertView;    private ListView mListView;    private List<FolderBean> mLists;    //接口回调    private OnSelectedListener mOnSelectedListener;    public interface OnSelectedListener{        void onSelected(FolderBean folderBean);    }    public void setPopSelected(OnSelectedListener mOnSelectedListener){        this.mOnSelectedListener=mOnSelectedListener;    }    public ImagePopupWindow(Context context,List<FolderBean> mLists) {        callWidthAndHeight(context);        mConvertView=LayoutInflater.from(context).inflate(R.layout.popup, null);        this.mLists=mLists;        setContentView(mConvertView);        setWidth(mWidth);        setHeight(mHeight);        setFocusable(true);        setTouchable(true);        setOutsideTouchable(true);        setBackgroundDrawable(new BitmapDrawable());        setTouchInterceptor(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                if(event.getAction()==MotionEvent.ACTION_OUTSIDE){                    dismiss();                    return true;                }                return false;            }        });        initView(context);        initEvent();    }private void initView(Context context) {    mListView=(ListView) mConvertView.findViewById(R.id.lv) ;    mListView.setAdapter(new ListDieAdapter(context, mLists));    }private void initEvent() {        mListView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> arg0, View arg1, int position,                    long arg3) {                mOnSelectedListener.onSelected(mLists.get(position));//接口回调            }        });    }/** * 计算popupWindow的宽度和高度 * @param context */    private void callWidthAndHeight(Context context) {        WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics dm=new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(dm);        mWidth=dm.widthPixels;        mHeight=(int) (dm.heightPixels*0.7);    }public class ListDieAdapter extends ArrayAdapter<FolderBean>{    private LayoutInflater mInflater;    //private List<FolderBean> mDatas;    public ListDieAdapter(Context context,              List<FolderBean> mLists) {        super(context, 0,  mLists);        mInflater=LayoutInflater.from(context);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        // TODO Auto-generated method stub        ViewHolder holder;        if(convertView==null){            holder=new ViewHolder();            convertView=mInflater.inflate(R.layout.popup_item, parent, false);            holder.mImg=(ImageView) convertView.findViewById(R.id.pop_item_iv);            holder.mDirName=(TextView) convertView.findViewById(R.id.pop_item_name);            holder.mDirCount=(TextView) convertView.findViewById(R.id.pop_item_count);            convertView.setTag(holder);        }else{            holder=(ViewHolder) convertView.getTag();        }        FolderBean fb=getItem(position);        holder.mImg.setImageResource(R.drawable.ic_launcher);        ImageLoader.getInstance(3,Type.LIFO).loadImage(fb.getFirstImagePath(), holder.mImg);        holder.mDirCount.setText(fb.getCount()+"");        holder.mDirName.setText(fb.getName());        return convertView;    }    private class ViewHolder{        ImageView mImg;        TextView mDirName;        TextView mDirCount;    }}}

ImageAdapter

import java.util.HashSet;import java.util.List;import java.util.Set;import android.content.Context;import android.graphics.Color;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.View.OnClickListener;import android.widget.BaseAdapter;import android.widget.ImageButton;import android.widget.ImageView;import com.example.imageloader.R;import com.example.imageloader.utils.ImageLoader;import com.example.imageloader.utils.ImageLoader.Type;public class ImageAdapter extends BaseAdapter{        private static Set<String> mSelectedImg=new HashSet<String>();        private String mDirPath;        private List<String> mImgPaths;        private LayoutInflater mInflater;        public ImageAdapter(Context context,List<String> mImgPaths,String mDirPath){            this.mDirPath=mDirPath;            this.mImgPaths=mImgPaths;            mInflater=LayoutInflater.from(context);        }        @Override        public int getCount() {            // TODO Auto-generated method stub            return mImgPaths.size();        }        @Override        public Object getItem(int position) {            // TODO Auto-generated method stub            return mImgPaths.get(position);        }        @Override        public long getItemId(int position) {            // TODO Auto-generated method stub            return position;        }        @Override        public View getView(final int position, View convertView, ViewGroup parent) {            final ViewHolder holder;            if(convertView==null){            holder=new ViewHolder();            convertView=mInflater.inflate(R.layout.item_gridview, parent,false);            holder.mImg=(ImageView) convertView.findViewById(R.id.iv);            holder.mSelect=(ImageButton) convertView.findViewById(R.id.ib);            convertView.setTag(holder);            }else{                holder=(ViewHolder) convertView.getTag();            }            //重置状态            holder.mImg.setImageResource(R.drawable.ic_launcher);            holder.mSelect.setImageResource(R.drawable.a0a);            holder.mImg.setColorFilter(null);            ImageLoader.getInstance(3, Type.LIFO).loadImage(mDirPath+ "/" +mImgPaths.get(position), holder.mImg);            final String filePath=mDirPath+ "/" +mImgPaths.get(position);               holder.mImg.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    if(mSelectedImg.contains(filePath)){                        mSelectedImg.remove(filePath);                        holder.mImg.setColorFilter(null);                        holder.mSelect.setImageResource(R.drawable.a0a);                    }else{                        mSelectedImg.add(filePath);                        holder.mImg.setColorFilter(Color.parseColor("#77000000"));                        holder.mSelect.setImageResource(R.drawable.a0_);                    }                    //notifyDataSetChanged();                }            });            if(mSelectedImg.contains(filePath)){                holder.mImg.setColorFilter(Color.parseColor("#77000000"));                holder.mSelect.setImageResource(R.drawable.a0_);            }            return convertView;        }        class ViewHolder{            ImageView mImg;            ImageButton mSelect;        }    }

FolderBean

public class FolderBean {    //当前文件夹路径    private String dir;    private String firstImagePath;    private String name;    private int count;    public FolderBean() {    }    public String getDir() {        return dir;    }    public void setDir(String dir) {        this.dir = dir;        //获取路径最后一个“/” 的索引        int lastIndexOf=this.dir.lastIndexOf("/");        this.name=this.dir.substring(lastIndexOf+1);    }    public String getFirstImagePath() {        return firstImagePath;    }    public void setFirstImagePath(String firstImagePath) {        this.firstImagePath = firstImagePath;    }    public String getName() {        return name;    }//  public void setName(String name) {//      this.name = name;//  }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }}

ImageLoader

import java.lang.reflect.Field;import java.util.LinkedList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v4.util.LruCache;import android.util.DisplayMetrics;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;public class ImageLoader {/** * 图片加载类 */    private static ImageLoader mInstance;//单例模式    private LruCache<String, Bitmap> mLruCache;//缓存    private ExecutorService mThreadPool;//线程池    private static final int THREAD_COUNT=1;//默认线程数    private Thread mPoolThread;//后台轮询线程    private Handler mPoolThreadHandler;//给线程发送消息的handler    private Handler mUIHandler;//更新图片UI的handler    private Type mType=Type.LIFO;//默认加载方式,队列调度方式    private LinkedList<Runnable> mTaskQueue;//任务队列    private Semaphore sePoolTH=new Semaphore(0);//信号量,解决并发问题    private Semaphore sePoolT;//利用信号量控制任务队列    //加载策略方式    public enum Type{        FIFO,LIFO    }    //初始化,可以让用户指定线程数,加载方式    private ImageLoader(int threadCont,Type type) {        init(threadCont,type);    }    private void init(int threadCont, Type type) {        //后台轮询线程        mPoolThread=new Thread(){            @Override            public void run() {                Looper.prepare();//启动                mPoolThreadHandler=new Handler(){                    @Override                    public void handleMessage(Message msg) {                    //当接收到消息,从线程池取出任务                        mThreadPool.execute(getTask());                        try {                            sePoolT.acquire();//接收信号,开始执行。没有信号就阻塞,从而控制队列                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    }                };                sePoolTH.release();//释放一个信号量,说明已经执行好了,可以执行sePoolTH.acquire()了                Looper.loop();//在后台不断的进行轮询            }        };        mPoolThread.start();        int maxMemory=(int) Runtime.getRuntime().maxMemory();//获取最大可用内存        int cacheMemory=maxMemory/8;  //取8分之1        mLruCache=new LruCache<String, Bitmap>(cacheMemory){            @Override//测量每个biamap的值            protected int sizeOf(String key, Bitmap value) {                // TODO Auto-generated method stub                return value.getRowBytes()*value.getHeight();            }        };        //初始化线程池        mThreadPool=Executors.newFixedThreadPool(threadCont);        mTaskQueue=new LinkedList<Runnable>();        mType=type;        sePoolT=new Semaphore(threadCont);//只能同时并发threadCont个,多的阻塞    }    //从任务队列取出一个方法        private Runnable getTask() {            if(mType==Type.FIFO){                return mTaskQueue.removeFirst();            }else if(mType==Type.LIFO){                return mTaskQueue.removeLast();            }            return null;        }    //单例    public static ImageLoader getInstance(int threadCont, Type type){        if(mInstance==null){            synchronized (ImageLoader.class) {                if(mInstance==null){                    mInstance=new ImageLoader(THREAD_COUNT,Type.LIFO);//默认的参数                }            }        }        return mInstance;           }    //根据path为imageView设置图片    public void loadImage(final String path,final ImageView imageView){        imageView.setTag(path);//        if(mUIHandler==null){            mUIHandler=new Handler(){                public void handleMessage(Message msg) {                    //获取得到的图片,设置到imageview                    ImgBeanHolder holder=(ImgBeanHolder) msg.obj;                    Bitmap bitmap=holder.bitmap;                    ImageView imageView=holder.imageView;                    String path=holder.path;                    if(imageView.getTag().toString().equals(path)){                        imageView.setImageBitmap(bitmap);                    }                };            };        }        //根据path在缓存中获取bitmap        Bitmap bm=getBitmapFromLruCache(path);        if(bm!=null){            Message message=Message.obtain();            ImgBeanHolder holder=new ImgBeanHolder();//这样下面这三个绝对是对应的。            holder.bitmap=bm;            holder.path=path;            holder.imageView=imageView;            message.obj=holder;            mUIHandler.sendMessage(message);        }else{            addTasks(new Runnable() {                @Override                public void run() {                    //加载图片                     //1,获取图片需要显示的大小                ImageSize imageSize=getImageViewSize(imageView);                    //2,压缩图片                Bitmap bm=decodeSampledBitmap(path,imageSize.width,imageSize.height);                   //3,把图片加入到缓存                    addBitampLruCache(path,bm);                    Message message=Message.obtain();                    ImgBeanHolder holder=new ImgBeanHolder();//这样下面这三个绝对是对应的。                    holder.bitmap=bm;                    holder.path=path;                    holder.imageView=imageView;                    message.obj=holder;                    mUIHandler.sendMessage(message);                    sePoolT.release();//释放信号量                }            });        }    }    protected void addBitampLruCache(String path, Bitmap bm) {        if(getBitmapFromLruCache(path)==null){            if(bm!=null){                mLruCache.put(path, bm);            }        }    }    //根据图片需要显示的宽和高对图片进行压缩    protected Bitmap decodeSampledBitmap(String path, int width, int height) {        BitmapFactory.Options options=new BitmapFactory.Options();        options.inJustDecodeBounds=true;        BitmapFactory.decodeFile(path, options);        options.inSampleSize=caculateInSampleSize(options,width,height);        //使用获取到insampleSize再次解析图片;        options.inJustDecodeBounds=false;        Bitmap bitmap=BitmapFactory.decodeFile(path, options);        return bitmap;    }    //计算压缩比    private int caculateInSampleSize(Options options, int reqwidth, int reqheight) {        int width=options.outWidth;   //图片的实际大小,要进行压缩的        int height=options.outHeight;        int sampleSize=1;        //如何图片的大小大于需求的大小,则进行压缩        if(width>reqwidth||height>reqheight){            int widthbili=Math.round(width*1.0f/reqwidth);            int heightbili=Math.round(height*1.0f/reqheight);             sampleSize=Math.max(widthbili, heightbili);        }        return sampleSize;    }    //根据imageview获取适当的压缩的宽和高     protected ImageSize getImageViewSize(ImageView imageView) {        ImageSize imageSize=new ImageSize();        DisplayMetrics dm= imageView.getContext().getResources().getDisplayMetrics();//获取屏幕        LayoutParams lp=imageView.getLayoutParams();        int width= imageView.getWidth();//获取实际宽度        if(width<=0){            width=lp.width;//获取imageview在layout声明的宽度        }        if(width<=0){            //width=imageView.getMaxWidth();//检查最大值            width= getImageValue(imageView, "mMaxWidth");        }        if(width<=0){            width=dm.widthPixels;        }        int height= imageView.getHeight();//获取实际宽度        if(height<=0){            height=lp.height;//获取imageview在layout声明的宽度        }        if(height<=0){        //  height=imageView.getMaxHeight();//检查最大值            height= getImageValue(imageView, "mMaxHeight");        }        if(height<=0){            height=dm.heightPixels;        }        imageSize.width=width;        imageSize.height=height;        return imageSize;               }    //通过反射获取imageView的某属性值    private static int getImageValue(Object object,String name){        int value=0;        try {            Field field=ImageView.class.getDeclaredField(name);            field.setAccessible(true);            try {                int fieldValue=field.getInt(object);                if(fieldValue>0 && fieldValue<Integer.MAX_VALUE){                    value=fieldValue;                }            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        } catch (NoSuchFieldException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return value;    }    private synchronized void addTasks(Runnable runnable) {        mTaskQueue.add(runnable);        try {//防止用到mPoolThreadHandler的时候还没初始化,如何执行到此的时候,还为空,会请求一个。这样就不回空指针了            if(mPoolThreadHandler==null)            sePoolTH.acquire();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        mPoolThreadHandler.sendEmptyMessage(0x110);    }    private Bitmap getBitmapFromLruCache(String key) {        return mLruCache.get(key);    }    //这个类防止加载的图片错乱,用一个对象统一。    private class ImgBeanHolder{        Bitmap bitmap;        ImageView imageView;        String path;            }    private class ImageSize{        int width;        int height;    }}
0 0
原创粉丝点击