仿微信图片选择器

来源:互联网 发布:淘宝直播怎么介绍自己 编辑:程序博客网 时间:2024/05/01 22:17

目标:

1、尽可能的避免内存溢出
a、根据图片的显示大小去压缩图片
b、使用缓冲对我们的图片进行管理(LruCache)

2、用户操作UI控件必须充分的流程
getView里面尽可能不去做耗时操作(异步加载+回调)

3、用户预期显示的图片尽可能的快(图片的加载策略的选择) LIFO,后进先出

ImageLoader
getView()
{
url->Bitmap
url->LruCache查找
->找到返回
->找不到 url->Task->TaskQuque且发送一个通知去提醒后台轮询线程
}

后台轮询线程
TaskQuque->Task->线程池去执行
new Thread(run(){while(){}}).start()//没有采用,效率低

               Handler+Looper+Message//异步消息处理框架,采用这个

Task->run()
{
根据url加载图片
1、获得图片显示的大小
2、使用Options对图片进行压缩
3、加载图片且放入LruCache
}

Task->TaskQueue->通知后台线程池->把Task放入到它的内部任务队列
修改:利用信号量

总结
ImageLoader
Handler+Looper+Message
handler在什么线程初始化就在那个线程

图片压缩
尺寸,options
setTag(url)

popupWindow 使用回调


涉及知识点:

1.信号量 Semaphore //阻塞和释放
2.获取应用的最大可用内存 //
int maxMemory = (int) Runtime.getRuntime().maxMemory();
3.线程池 //创建线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
4.队列 // mTaskQuequ = new LinkedList();
5.单例模式 //getInstance()
6.屏幕的像素 //DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
7.压缩图片 // 使用options
8.屏幕变暗(变灰) //WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 0.3f;
getWindow().setAttributes(lp);

9.扫描图片 // 使用 Uri + ContentResolver +Cursor
10.文件过滤 //FilenameFilter
11.数组转list //list = Arrays.asList(str【】);
12.复用 // converView和viewholder
13.Set // List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复
14.private static Set mState = new HashSet(); //如果没有static 在切换文件时,选择状态不会被保存
15.PopupWindow里面 setBackgroundDrawable(new BitmapDrawable());//设置外面可以点击,点击外部区域使它消失
16.拦截点击 //setTouchInterceptor
17.使用interface给actvity回调
18.GridView 里面 android:stretchMode=”columnWidth” 缩放与列宽大小同步
19.ImageView 里面 android:scaleType=”centerCrop” 均 衡的缩放图像(保持图像原始比例)
20.PopupWindow 的动画 anim/目录下声明,styles.xml声明 ,设置动画mPopupWindow.setAnimationStyle(R.style.dir_PopupWindow_anim);


效果
这里写图片描述

-

这里写图片描述


核心工作类ImageLoader

package com.example.day0301.util;import java.util.LinkedList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import android.annotation.SuppressLint;import android.app.ActionBar.LayoutParams;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.text.Layout;import android.util.DisplayMetrics;import android.view.Display;import android.widget.ImageView;import android.widget.RelativeLayout;/** *  * @author Administrator * 图片加载类 */public class ImageLoader {    public static ImageLoader mInstance;    /**     * 图片缓存的核心对象     */    private LruCache<String, Bitmap> mLruCache;    /**     * 线程池     */    private ExecutorService mThreadPool;    private static final int DEAFULT_THREAD_COUNT = 1;    private Type mType = Type.LIFO;    /**     * 任务队列     * 里面是链表     */    private LinkedList<Runnable> mTaskQuequ;    /**     * 后台轮询线程     */    private Thread mPoolThread;    private Handler mPoolThreadHandler;    /**     * UI线程中的Handler     */    private Handler mUIHandler;    private Semaphore mPoolThreadHandlerSemaphore = new Semaphore(0);    private Semaphore mSemaphoreThreadPool;    public enum Type {        FIFO,LIFO    }    public ImageLoader(int threadCount, Type type) {        init(threadCount,type);    }    /**     * 初始化     * @param mThreadCount     * @param type     */    @SuppressLint("HandlerLeak")    private void init(int threadCount, Type type) {        //后台轮询线程        mPoolThread = new Thread() {            @Override            public void run() {                Looper.prepare();                mPoolThreadHandler = new Handler(){                    @Override                    public void handleMessage(Message msg) {                        //通过线程池取出任务去执行                        mThreadPool.execute(getTask());                        try {                            mSemaphoreThreadPool.acquire();                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                };                //释放一个信号量                mPoolThreadHandlerSemaphore.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) {                return value.getRowBytes() * value.getHeight();            }        };        //创建线程池        mThreadPool = Executors.newFixedThreadPool(threadCount);        mTaskQuequ = new LinkedList<Runnable>();        mType = type;        mSemaphoreThreadPool = new Semaphore(threadCount);    }    /**     * 从任务队列取出一个方法     * @return     */    private Runnable getTask() {        if (mType == Type.FIFO) {            return mTaskQuequ.removeFirst();        } else if (mType == Type.LIFO){            return mTaskQuequ.removeLast();        }        return null;    }    //单例模式    public static ImageLoader getInstance(int threadCount,Type tpye) {        //没有做同步处理,为了提高效率        if (mInstance == null) {            synchronized (ImageLoader.class) {                if (mInstance == null) {                    mInstance = new ImageLoader(threadCount, tpye);                }            }        }        return mInstance;    }    /**     * g根据path为ImageView设置图片     * @param path     * @param imageView     */    @SuppressLint("HandlerLeak")    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 bm = holder.bitmap;                    ImageView imageView = holder.imageView;                    String path = holder.Path;                    //将Path与getTag存储路径进行比较                    if (imageView.getTag().toString().equals(path)) {                        imageView.setImageBitmap(bm);                    }                }            };        }        //根据Path在缓存中获取bitmap        Bitmap bm = getBitmapFromLruCache(path);        if (bm != null) {            refreshBitmap(path, imageView, bm);        } else {            addTasks(new Runnable() {                @Override                public void run() {                    // 加载图片                    // 图片的压缩                    // 1、获得图片需要显示的大小                    ImageSize imageSize = getImageViewSize(imageView);                    // 2、压缩图片                    Bitmap bm = decodeSampledBitmapFromPath(path, imageSize.width, imageSize.height);                    // 3、把图片加入到缓存                    addBitmapToLruCache(path, bm);                    //回调                    refreshBitmap(path, imageView, bm);                    mSemaphoreThreadPool.release();                }            });        }    }    private void refreshBitmap(final String path, final ImageView imageView,            Bitmap bm) {        Message message = Message.obtain();        ImgBeanHolder holder = new ImgBeanHolder();        holder.bitmap = bm;        holder.imageView = imageView;        holder.Path = path;        message.obj = holder;        mUIHandler.sendMessage(message);    }    /**     *将图片加入LruCache      * @param pathm     * @param bm     */    protected void addBitmapToLruCache(String path, Bitmap bm) {        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) {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;//获取图片的宽和高,但是不载入内存中        BitmapFactory.decodeFile(path, options);//options获得了图片实际的宽和高        options.inSampleSize = caculateInSampleSize(options,width,height);        //使用获取到的InSampleSize再次解析图片        options.inJustDecodeBounds = false;//获取图片的宽和高,但是载入内存中        Bitmap bitmap = BitmapFactory.decodeFile(path, options);        return bitmap;    }    /**     * 根据需求的宽和高以及实际的宽和高计算SampleSize     * @param options     * @param width     * @param height     * @return     */    private int caculateInSampleSize(Options options, int reqWidth, int reHheight) {        int width = options.outWidth;        int height = options.outHeight;        int inSampleSize = 1;        if(width > reqWidth || height > reHheight) {            int widthRadio = Math.round(width * 1.0f / reqWidth);            int heightRadio = Math.round(height * 1.0f / reHheight);            inSampleSize = Math.max(widthRadio, heightRadio);        }        return inSampleSize;    }    private class ImageSize {        int width;        int height;    }    /**     * 根据ImageView获得适当的压缩的宽和高     * @param imageView     * @return     */    @SuppressLint("NewApi")    protected ImageSize getImageViewSize(ImageView imageView) {        ImageSize imageSize = new ImageSize();        //屏幕的宽度        DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();        RelativeLayout.LayoutParams lp =  (android.widget.RelativeLayout.LayoutParams) imageView.getLayoutParams();        int width = imageView.getWidth();        if (width <= 0) {            width = lp.width;        }        if (width <= 0) {            width = imageView.getMaxWidth();        }        if (width <= 0) {            width = metrics.widthPixels;        }        int height = imageView.getHeight();        if (height <= 0) {            height = lp.height;        }        if (height <= 0) {            height = imageView.getMaxHeight();        }        if (height <= 0) {            height = metrics.heightPixels;        }        imageSize.width = width;        imageSize.height = height;        return imageSize;    }    private synchronized void addTasks(Runnable runnable) {        mTaskQuequ.add(runnable);        // if (mPoolThreadHandler == null) wait();        if (mPoolThreadHandler == null) {            try {                mPoolThreadHandlerSemaphore.acquire();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        mPoolThreadHandler.sendEmptyMessage(0x110);    }    //持有对象    private class ImgBeanHolder {        Bitmap bitmap;        ImageView imageView;        String Path;    }    private Bitmap getBitmapFromLruCache(String path) {        return mLruCache.get(path);    }}

Main

package com.example.day0301;import java.io.File;import java.io.FilenameFilter;import java.lang.reflect.Array;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Set;import com.example.day0301.ListImageDirPopupWindow.onItemClickInterface;import com.example.day0301.adapter.ImageAdapter;import com.example.day0301.bean.FolderBean;import com.example.day0301.util.ImageLoader;import com.example.day0301.util.ImageLoader.Type;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.util.Log;import android.view.LayoutInflater;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;import android.widget.PopupWindow.OnDismissListener;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity implements onItemClickInterface{    private GridView mGridView;    private ImageAdapter mImageAdapter;    private RelativeLayout mBottomLy;    private TextView mDirName;    private TextView mDirCount;    private int mMaxCount = 0;    private File mCurrentFile;    private List<String> mImgs;    private List<FolderBean> mFolderBeans = new ArrayList<FolderBean>();    private ProgressDialog mProgressDialog;    private ListImageDirPopupWindow mPopupWindow;    private static final int DATA_LOADED = 1;     private Handler mHandler = new Handler(){        public void handleMessage(android.os.Message msg) {            if (msg.what == DATA_LOADED) {                if (mProgressDialog.isShowing()) {                    mProgressDialog.dismiss();                }                //绑定数据到View中                data2view();                initPopupWindow();            }        };    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initDatas();        initEvent();    }    protected void initPopupWindow() {        mPopupWindow = new ListImageDirPopupWindow(this,mFolderBeans);        mPopupWindow.setItemClickListener(this);        mPopupWindow.setOnDismissListener(new OnDismissListener() {            @Override            public void onDismiss() {                lightOn();            }        });    }    /**     * 内容区域变亮     */    protected void lightOn() {        WindowManager.LayoutParams lp = getWindow().getAttributes();        lp.alpha = 1.0f;        getWindow().setAttributes(lp);    }    protected void lightOff() {        WindowManager.LayoutParams lp = getWindow().getAttributes();        lp.alpha = 0.3f;        getWindow().setAttributes(lp);    }    protected void data2view() {        if (mCurrentFile == null) {            Toast.makeText(this, "为扫描到任何图片", Toast.LENGTH_SHORT).show();            return ;        }        //把数组赋值给list        mImgs = Arrays.asList(mCurrentFile.list(new FilenameFilter() {            @Override            public boolean accept(File dir, String filename) {                if (filename.endsWith(".jpg") || filename.endsWith(".png") || filename.endsWith(".jpeg")) {                    return true;                }                return false;            }        }));        mImageAdapter = new ImageAdapter(this, mImgs, mCurrentFile.getAbsolutePath());        mGridView.setAdapter(mImageAdapter);        mDirCount.setText(mMaxCount+"");        mDirName.setText(mCurrentFile.getName());    }    private void initEvent() {        mBottomLy.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mPopupWindow.setAnimationStyle(R.style.dir_PopupWindow_anim);                mPopupWindow.showAsDropDown(mBottomLy, 0, 0);                lightOff();            }        });    }    /**     * 利用ContentProvider扫描图片     */    private void initDatas() {        //扫描图片        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            Toast.makeText(this, "当前存储卡不可用", Toast.LENGTH_SHORT).show();            return;        }        mProgressDialog = ProgressDialog.show(this,null,"正在加载...");        new Thread() {            @Override            public void run() {                //所有图片的Uri                Uri mImgUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                ContentResolver cr = MainActivity.this.getContentResolver();                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.setFirstImgPath(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(".png") || filename.endsWith(".jpeg")) {                                return true;                            }                            return false;                        }                    }).length;                    folderBean.setCount(picSize);                    mFolderBeans.add(folderBean);                    if (picSize > mMaxCount) {                        mMaxCount = picSize;                        mCurrentFile = parentFile;                    }                }                cursor.close();                mHandler.sendEmptyMessage(DATA_LOADED);                Log.v("TAG", "mCount="+mMaxCount);            }        }.start();    }    private void initView() {        mGridView = (GridView) findViewById(R.id.id_grid_view);        mBottomLy = (RelativeLayout) findViewById(R.id.id_bottom_ly);        mDirName = (TextView) findViewById(R.id.id_dir_name);        mDirCount = (TextView) findViewById(R.id.id_dir_count);    }    @Override    public void onItemClick(FolderBean folderBean) {        mCurrentFile = new File(folderBean.getDir());        mMaxCount = folderBean.getCount();        data2view();        mPopupWindow.dismiss();    }}

main.xml

<RelativeLayout     android:layout_width="match_parent"    android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">    <GridView         android:id="@+id/id_grid_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:cacheColorHint="@android:color/transparent"        android:horizontalSpacing="3dp"        android:listSelector="@android:color/transparent"        android:numColumns="3"        android:stretchMode="columnWidth"        android:verticalSpacing="3dp"></GridView>    <RelativeLayout         android:id="@+id/id_bottom_ly"        android:layout_width="match_parent"        android:layout_height="50dp"        android:layout_alignParentBottom="true"        android:background="#ee000000"        android:clipChildren="true"        >        <TextView             android:id="@+id/id_dir_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_centerVertical="true"            android:paddingLeft="10dp"            android:text="所有图片"            android:textColor="#fff"/>        <TextView             android:id="@+id/id_dir_count"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:paddingLeft="10dp"            android:text="100张"            android:textColor="#fff"/>    </RelativeLayout></RelativeLayout>

ImageAdapter

package com.example.day0301.adapter;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.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageButton;import android.widget.ImageView;import com.example.day0301.R;import com.example.day0301.util.ImageLoader;import com.example.day0301.util.ImageLoader.Type;public class ImageAdapter extends BaseAdapter {    private String mDirPath;    private List<String> mImgPaths;    private LayoutInflater mInflater;    private static Set<String> mState = new HashSet<String>();    public ImageAdapter(Context context, List<String> mDatas, String path) {        this.mDirPath = path;        this.mImgPaths = mDatas;        mInflater = LayoutInflater.from(context);     }    @Override    public int getCount() {        return mImgPaths.size();    }    @Override    public Object getItem(int position) {        return mImgPaths.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        final ViewHolder viewHolder ;;        if (convertView == null) {            convertView = mInflater.inflate(R.layout.item_gridview, null);            viewHolder = new ViewHolder();            viewHolder.mImg = (ImageView) convertView.findViewById(R.id.id_item_image);            viewHolder.mSelect =  (ImageButton) convertView.findViewById(R.id.id_item_select);            convertView.setTag(viewHolder);        } else {            viewHolder = (ViewHolder) convertView.getTag();        }        //重置状态        viewHolder.mImg.setImageResource(R.drawable.pictures_no);        viewHolder.mSelect.setImageResource(R.drawable.picture_unselected);        viewHolder.mImg.setColorFilter(null);        ImageLoader.getInstance(3, Type.LIFO).loadImage(mDirPath+"/"+mImgPaths.get(position), viewHolder.mImg);        final String filePath = mDirPath+"/"+mImgPaths.get(position);        viewHolder.mImg.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (mState.contains(filePath)) {                    mState.remove(filePath);                    viewHolder.mImg.setColorFilter(null);                    viewHolder.mSelect.setImageResource(R.drawable.picture_unselected);                } else {                    mState.add(filePath);                    viewHolder.mImg.setColorFilter(Color.parseColor("#77000000"));                    viewHolder.mSelect.setImageResource(R.drawable.pictures_selected);                }//              notifyDataSetChanged(); 会闪屏            }        });        if (mState.contains(filePath)) {            viewHolder.mImg.setColorFilter(Color.parseColor("#77000000"));            viewHolder.mSelect.setImageResource(R.drawable.pictures_selected);        }         return convertView;    }    private class ViewHolder {        ImageView mImg;        ImageButton mSelect;    }}

item_gridview.xml

<RelativeLayout    android:layout_width="match_parent"    android:layout_height="match_parent"     xmlns:android="http://schemas.android.com/apk/res/android" >    <ImageView         android:id="@+id/id_item_image"        android:layout_width="match_parent"        android:layout_height="100dp"        android:scaleType="centerCrop"        android:src="@drawable/pictures_no"        />    <ImageButton         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/id_item_select"        android:layout_alignParentTop="true"        android:layout_alignParentRight="true"        android:layout_marginTop="3dp"        android:layout_marginRight="3dp"        android:background="@null"        android:clickable="false"        android:src="@drawable/picture_unselected"/></RelativeLayout>

FolderBean

package com.example.day0301.bean;public class FolderBean {    private String dir;    private String firstImgPath;    private String name;    private int count;    public String getDir() {        return dir;    }    public void setDir(String dir) {        this.dir = dir;        int lastIndexOf = this.dir.indexOf("/");        this.name = this.dir.substring(lastIndexOf);    }    public String getFirstImgPath() {        return firstImgPath;    }    public void setFirstImgPath(String firstImgPath) {        this.firstImgPath = firstImgPath;    }    public String getName() {        return name;    }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }}

ListImageDirPopupWindow

package com.example.day0301;import java.util.List;import com.example.day0301.bean.FolderBean;import com.example.day0301.util.ImageLoader;import com.example.day0301.util.ImageLoader.Type;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.drawable.BitmapDrawable;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;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;@SuppressLint("ClickableViewAccessibility")public class ListImageDirPopupWindow extends PopupWindow {    private int mWidth;    private int mHeight;    private View mConvertView;    private ListView mListView;    private List<FolderBean> mDatas;    public interface onItemClickInterface {         void onItemClick(FolderBean folderBean);    }    private onItemClickInterface mItemClickListener = null;    public void setItemClickListener(onItemClickInterface mItemClickListener) {        this.mItemClickListener = mItemClickListener;    }     @SuppressWarnings("deprecation")    public ListImageDirPopupWindow (Context context, List<FolderBean> datas) {        calWidthAndHeight(context);        mConvertView = LayoutInflater.from(context).inflate(R.layout.popup_main, null);        mDatas = datas;        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;            }        });        initViews(context);        initEvent();    }    private void initViews(Context context) {        mListView = (ListView) mConvertView.findViewById(R.id.id_pop_list);        mListView.setAdapter(new ListDirAdapter(context,mDatas));    }    private void initEvent() {        mListView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view,                    int position, long id) {                if (mItemClickListener != null) {                    mItemClickListener.onItemClick(mDatas.get(position));                }            }        });    }    /**     * 计算PopupWindow的宽度和高度     * @param context     */    private void calWidthAndHeight(Context context) {        //1        DisplayMetrics metrics = context.getResources().getDisplayMetrics();        //2        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        mWidth = outMetrics.widthPixels;        mHeight = (int) (outMetrics.heightPixels * 0.7);        Log.v("TAG", metrics.widthPixels+","+outMetrics.widthPixels);    }    private class ListDirAdapter extends ArrayAdapter<FolderBean> {        private LayoutInflater mInflater;        private List<FolderBean> mDatas;        public ListDirAdapter(Context context, List<FolderBean> objects) {            super(context,0,objects);            mInflater = LayoutInflater.from(context);            mDatas = objects;        }        @Override        public FolderBean getItem(int position) {            return mDatas.get(position);        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder viewHolder = null;            if (convertView == null) {                convertView = mInflater.inflate(R.layout.item_popup_main, parent,false);                viewHolder = new ViewHolder();                viewHolder.mImg = (ImageView) convertView.findViewById(R.id.id_dir_item_image);                viewHolder.mDirName = (TextView) convertView.findViewById(R.id.id_dir_item_name);                viewHolder.mDirCount = (TextView) convertView.findViewById(R.id.id_dir_item_count);                convertView.setTag(viewHolder);                } else {                viewHolder = (ViewHolder) convertView.getTag();                }            FolderBean bean = getItem(position);            //重置            viewHolder.mImg.setImageResource(R.drawable.pictures_no);            ImageLoader.getInstance(3, Type.LIFO).loadImage(bean.getFirstImgPath(), viewHolder.mImg);            String name = bean.getName();            name = name.substring(name.lastIndexOf("/"));            viewHolder.mDirName.setText(name);            viewHolder.mDirCount.setText(bean.getCount()+"");            return convertView;        }        private class ViewHolder {            ImageView mImg;            TextView mDirName;            TextView mDirCount;        }    }}

popup_main.xml

<LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"     xmlns:android="http://schemas.android.com/apk/res/android" >    <ListView         android:id="@+id/id_pop_list"        android:layout_width="match_parent"        android:layout_height="match_parent"></ListView></LinearLayout>

item_popup_main.xml

<RelativeLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"     xmlns:android="http://schemas.android.com/apk/res/android"     android:background="#fff"      >    <ImageView         android:id="@+id/id_dir_item_image"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_alignParentLeft="true"        android:background="@drawable/pic_dir"        android:paddingBottom="17dp"        android:paddingLeft="12dp"        android:paddingRight="12dp"        android:paddingTop="9dp"        android:scaleType="fitXY"        android:src="@drawable/ic_launcher"/>    <LinearLayout         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:layout_marginLeft="10dp"        android:layout_toRightOf="@id/id_dir_item_image"        android:orientation="vertical">        <TextView             android:id="@+id/id_dir_item_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="所有图片"            android:textSize="10sp"/>        <TextView             android:id="@+id/id_dir_item_count"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="100"            android:textSize="10sp"/>    </LinearLayout>    <ImageView         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        android:layout_marginRight="20dp"        android:src="@drawable/dir_choose"        /></RelativeLayout>

PopupWindow动画
/anim目录下
slide_up.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">    <translate         android:duration="200"        android:fromXDelta="0"        android:fromYDelta="100%"        android:toXDelta="0"        android:toYDelta="0"/></set>

slide_down.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">    <translate         android:duration="200"        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="0"        android:toYDelta="100%"/></set>

styles.xml

 <style name="dir_PopupWindow_anim">        <item name="android:windowEnterAnimation">@anim/slide_up</item>        <item name="android:windowExitAnimation">@anim/slide_down</item>    </style>

转载于:
http://www.imooc.com/learn/489(视频)
http://blog.csdn.net/lmj623565791/article/details/39943731(博客带源码)

0 0
原创粉丝点击