美文网首页2022
Android自定义相册,查看手机图片

Android自定义相册,查看手机图片

作者: Android绝世小菜鸟 | 来源:发表于2017-01-01 16:17 被阅读0次

    最近因为公司需求需要做一个自定义的相册,因为手机自带的相册没有这种可以选取多张图片的功能,先上gif图,看效果(功能可以看出来,不知道为什么gif这么稀烂。。。)

    GIF.gif

    简单功能都实现了,主要点是对图片的查询,然后设置了两个popupWindow来显示小相册和点击放大的效果,比较简单。(代码里面会有一些简单的工具类,看名字可以看出来是干什么的)

    查询手机中的图片路径

    步骤:
    1.查询图片的path
    2.由图片path获取其他信息(该图片所在文件夹的路径,文件夹的名字,文 件夹下的图片个数)
    3.定义一个图片Model,来保存及对图片信息的传递,以便展示出来
    4.通过文件夹的list()方法,可以获取每一个小相册下的图片文件

    上代码。。。

    //获取图片的路径和父路径 及 图片size
       private void getImages() {
           if (!Environment.getExternalStorageState().equals(
                   Environment.MEDIA_MOUNTED)) {
               ViewKit.shortToast("检测到没有内存卡");
               return;
           }
           showLoading();
           new Thread(new Runnable() {
               @Override
               public void run() {
                   Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                   ContentResolver mContentResolver = GalleryActivity.this.getContentResolver();
    
                   Cursor mCursor = mContentResolver.query(mImageUri, null,
                           MediaStore.Images.Media.MIME_TYPE + "=? or "+
                           MediaStore.Images.Media.MIME_TYPE + "=? or "+
                           MediaStore.Images.Media.MIME_TYPE + "=?",
                           new String[]{"image/jpeg", "image/png","image/jpg"},
                           MediaStore.Images.Media.DATE_TAKEN +" DESC");//获取图片的cursor,按照时间倒序(发现没卵用)
    
                   while (mCursor.moveToNext()) {
                       String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));// 1.获取图片的路径
                       File parentFile = new File(path).getParentFile();
                       if (parentFile == null)
                           continue;//不获取sd卡根目录下的图片
                       String parentPath = parentFile.getAbsolutePath();//2.获取图片的文件夹信息
                       String parentName = parentFile.getName();
                       ImageFloder imageFloder ;//自定义一个model,来保存图片的信息  
    
           //这个操作,可以提高查询的效率,将查询的每一个图片的文件夹的路径保存到集合中,  
           //如果存在,就直接查询下一个,避免对每一个文件夹进行查询操作  
                       if (mDirPaths.contains(parentPath)) {
                           continue;
                       } else {
                           mDirPaths.add(parentPath);//将父路径添加到集合中
                           imageFloder = new ImageFloder();
                           imageFloder.setFirstImagePath(path);
                           imageFloder.setDir(parentPath);
                           imageFloder.setName(parentName);
                       }
                       List<String>  strings = null;
                       try {
                        strings =  Arrays.asList(parentFile.list(getFileterImage()));
                       } catch (Exception e) {
                           e.printStackTrace();
                       }
                       int  picSize = strings.size();//获取每个文件夹下的图片个数
                       imageFloder.setCount(picSize);//传入每个相册的图片个数
                       mImageFloders.add(imageFloder);//添加每一个相册
           //获取图片最多的文件夹信息(父目录对象和个数,使得刚开始显示的是最多图片的相册
                       if (picSize > mPicsSize) {  
                           mPicsSize = picSize;
                           mImgDir = parentFile;
                       }
                   }
                   mCursor.close();
                   mDirPaths = null;
                   mHandler.sendEmptyMessage(1);
               }
           }).start();
       }
    

    这是Model类,贴出来,方便观看

    public class ImageFloder {
        private int count;//文件夹下的图片个数
        private String firstImagePath;//第一张图片的路径 传这个给小相册图片显示
        private String dir;//文件夹路径
        private String name;//文件夹的名字
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public String getFirstImagePath() {
            return firstImagePath;
        }
    
        public void setFirstImagePath(String firstImagePath) {
            this.firstImagePath = firstImagePath;
        }
    
        public String getDir() {
            return dir;
        }
    
        public void setDir(String dir) {
            this.dir = dir;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    

    还记得上面的handler操作吗,查询图片是一个耗时的操作,为了更新ui,也为了方便观看,就使用了handler的方式,这样代码也比较整洁,下面这个小代码,就是接下来的步骤了

    Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                setAdapterData();//设置图片的显示
                cancelLoading();//取消加载框
                initListDirPopupWindw();//初始化小相册的popupWindow
                initChekcBox();//初始化checkbox集合,防止checkBox的错乱
            }
        };
    

    设置适配器(采用的RecycleVIew,自己做的封装)

        //设置适配器数据
    private void setAdapterData() {
        if (mImgDir == null) {
            ViewKit.shortToast("没有查询到图片");
            return;
        }
        tv_pop_gallery.setText(mImgDir.getName());
        try {
            mImgs = Arrays.asList(mImgDir.list(getFileterImage()));//获取文件夹下的图片集合
        }catch (Exception e){
            e.printStackTrace();
        }
        //查询出来的图片是正序的,为了让图片按照时间倒序显示,对其倒序操作
        Collections.sort(mImgs, new Comparator<String>() {
            @Override
            public int compare(String lhs, String rhs) {
                return -1;
            }
        });
    
        mAdapter = new GalleryAdapter(gallery_recycleView, mImgs, R.layout.item_gallery_camera);
        gallery_recycleView.setLayoutManager(new GridLayoutManager(this, 3));
        gallery_recycleView.addItemDecoration(new DividerGridItemDecoration(this));
        gallery_recycleView.setAdapter(mAdapter);
    }
    

    适配器:

    //适配器
        private class GalleryAdapter extends BaseRecyclerAdapter<String> {
            List<String> datas;
            String picPath;
            ImageView iv_gallery;
            CheckBox cb_gallery;
    
            public GalleryAdapter(RecyclerView v, List<String> datas, int itemLayoutId) {
                super(v, datas, itemLayoutId);
                this.datas = datas;
            }
    
            @Override
            public void convert(final RecyclerHolder holder, String item, final int position) {
                iv_gallery = holder.getView(R.id.iv_gallery);
                cb_gallery = holder.getView(R.id.cb_gallery);
                iv_gallery.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, DensityKit.getScreenW() / 3));
                picPath = mImgDir.getAbsolutePath() + "/" + datas.get(position);
                BitmapKit.loadLocalImage(iv_gallery, picPath);//这里采用的是Glide为ImageVIew加载图片,很方便,这里对Glide进行了工具类的封装
    
                //显示大图
                iv_gallery.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        initBigPicPopupWindw(mImgDir.getAbsolutePath() + "/" + datas.get(position));
                    }
                });
    
                //checkBox
                cb_gallery.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        CheckBox checkBox = (CheckBox) v;
                        if (realCount >= 9 && !selectList.get(position)) {
                            ViewKit.shortToast("最多可以选择9张图片");
                            selectList.put(position, false);
                        } else{
                            selectList.put(position, !selectList.get(position));
                        }
    
                        for (Map.Entry<Integer, Boolean> entry : selectList.entrySet()) {
                            entry.getKey();
                            Boolean value = entry.getValue();
                            if (value) {
                                checkCount++;
                            }
                        }
                        tv_count_gallery.setText("(" + checkCount + ")");
                        tv_confirm_gallery.setVisibility(checkCount>0?View.VISIBLE:View.GONE);
                        realCount = checkCount;
                        checkCount = 0;
                        checkBox.setChecked(selectList.get(position));
                    }
                });
                if(selectList!=null)
                    cb_gallery.setChecked(selectList.get(position));
            }
        }
    }
    
    

    左侧popupWindow小相册的定义

    //设置相册PopupWindow
       private void initListDirPopupWindw() {
           mListImageDirPopupWindow = new ListImageDirPopupWindow(this, mImageFloders);
           mListImageDirPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
               @Override
               public void onDismiss() {
                   setToRightDrawable(R.drawable.arrow_bottom);
               }
           });
           mListImageDirPopupWindow.setOnImageDirSelected(new ListImageDirPopupWindow.OnImageDirSelected() {  
             //点击item之后的回调
               @Override
               public void selected(ImageFloder floder) {
                   mListImageDirPopupWindow.showAtDropDownCenter(tv_confirm_gallery);
                   setToRightDrawable(R.drawable.arrow_bottom);
                   realCount = 0;
                   tv_pop_gallery.setText(floder.getName());
                   tv_count_gallery.setText("(0)");
                   tv_confirm_gallery.setVisibility(View.GONE);
                   File file = new File(floder.getDir());
                   List<String> picFileList = null;
                   try {
                       picFileList =   Arrays.asList(file.list(getFileterImage()));
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
    
                   Collections.sort(picFileList, new Comparator<String>() {
                       @Override
                       public int compare(String lhs, String rhs) {
                           return -1;
                       }
                   });
                 //重新设置数据和checkBox初始化
                   mImgDir = file;
                   mImgs = picFileList;
                   initChekcBox();
                   mAdapter = new GalleryAdapter(gallery_recycleView, picFileList, R.layout.item_gallery_camera);
                   gallery_recycleView.setAdapter(mAdapter);
               }
           });
       }
    

    相册PopupWIndow的代码:

    public class ListImageDirPopupWindow extends PopupWindow {
       RecyclerView recycl_camera_list;
       public ListImageDirPopupWindow(Context context, List<ImageFloder> mImageFloders) {
           View conentView = LayoutInflater.from(context).inflate(R.layout.view_dir_camera, null);
           recycl_camera_list = (RecyclerView) conentView.findViewById(R.id.recycl_camera_list);
           setContentView(conentView);
    
           ListAdapter listAdapter = new ListAdapter(recycl_camera_list, mImageFloders, R.layout.item_list_camera);
           recycl_camera_list.setLayoutManager(new LinearLayoutManager(context));//设置垂直
           recycl_camera_list.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
           recycl_camera_list.setAdapter(listAdapter);
           listAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
               @Override
               public void onItemClick(View view, Object data, int position) {
                   if (data instanceof ImageFloder) {
                       ImageFloder imageFloder = (ImageFloder) data;
                       onImageDirSelected.selected(imageFloder);
                   }
               }
           });
           setAnimationStyle(R.style.popup_camera);
           setFocusable(true);
           setTouchable(true);
    
           setOutsideTouchable(true);
           ColorDrawable background = new ColorDrawable(0xffffff);
           setBackgroundDrawable(background);
           setWidth((int) (DensityKit.getScreenW()/2));
           setHeight(DensityKit.getScreenH()/3);
    
       }
    
    
       class ListAdapter extends BaseRecyclerAdapter<ImageFloder> {
    
           public ListAdapter(RecyclerView v, List<ImageFloder> datas, int itemLayoutId) {
               super(v, datas, itemLayoutId);
           }
    
           @Override
           public void convert(RecyclerHolder holder, final ImageFloder imageFloder, int position) {
               ImageView iv_first_image = holder.getView(R.id.iv_first_image);
               TextView tv_count_list = holder.getView(R.id.tv_count_list);
               TextView tv_name_list = holder.getView(R.id.tv_name_list);
    
               BitmapKit.loadLocalImage(iv_first_image, imageFloder.getFirstImagePath());
               tv_count_list.setText("(" + imageFloder.getCount() + ")");
               tv_name_list.setText(imageFloder.getName());
    
           }
       }
    
       public void showAtDropDownCenter(View parent) {
           if (!isShowing()) {
               setAnimationStyle(R.style.popup_camera);
               int[] location = new int[2];
               parent.getLocationOnScreen(location);//获取以屏幕为原点的位置
               showAtLocation(parent,Gravity.TOP|Gravity.LEFT,0,location[1]-getHeight());
    //            showAtLocation(parent,Gravity.TOP,(location[0]-getWidth())/2, location[1]-getHeight());
    //            showAtLocation(parent, Gravity.NO_GRAVITY, location[0], location[1]-getHeight()); 三种方式都可以 原理是一样的
           } else {
               dismiss();
           }
       }
       //点击之后的接口回调
       private OnImageDirSelected onImageDirSelected;
       public void setOnImageDirSelected(OnImageDirSelected onImageDirSelected) {
           this.onImageDirSelected = onImageDirSelected;
       }
       public interface OnImageDirSelected {
           void selected(ImageFloder floder);
       }
    }
    
    

    杂⑦杂⑧的代码,懒的搞了,都贴出来(都有小注释)

     //设置大图片的PopupWindow
       private void initBigPicPopupWindw(String path) {
           BigImagePopup bigImagePopup = new BigImagePopup(this);
           bigImagePopup.setUrl(path);
           bigImagePopup.showAtDropDownCenter(tv_confirm_gallery);
       }
    
    
       //导航栏点击事件
       @Override
       public void onClick(View v) {
           int i = v.getId();
           if (i == R.id.tv_pop_gallery) {
              setToRightDrawable(R.drawable.arrow_up);
               mListImageDirPopupWindow.showAtDropDownCenter(tv_confirm_gallery);
           } else if (i == R.id.tv_confirm_gallery) {
    
               ArrayList<String> pathList = new ArrayList<>();
               for (Map.Entry<Integer, Boolean> entry : selectList.entrySet()) {
                   Boolean isChecked = entry.getValue();
                   if (isChecked) {
                       Integer position = entry.getKey();
                       String checkPath = mImgDir.getAbsolutePath() + "/" + mImgs.get(position);
                       pathList.add(checkPath);
                   }
               }
               backUrl(pathList);
           }
       }
    
    
       //intent
       public static Intent createIntent(Context context) {
           Intent intent = new Intent(context, GalleryActivity.class);
           intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
           return intent;
       }
    
    
       //返回的图片路径集合
       private void backUrl(ArrayList<String> pathList) {
           Intent intent = new Intent();
           intent.putStringArrayListExtra("imageUrl", pathList);
           setResult(RESULT_OK, intent);
           finish();
       }
    
    
       // 初始化 设置所有checkbox都为未选择
       private void initChekcBox() {
           selectList = new HashMap<Integer, Boolean>();
           if (mImgs != null && mImgs.size() > 0) {
               for (int i = 0; i < mImgs.size(); i++) {
                   selectList.put(i, false);
               }
           }
       }
    
    
       //动态改变text的toRightDrawable
       private void setToRightDrawable(int drawalbeId){
           Drawable drawable= getResources().getDrawable(drawalbeId);
           drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
           tv_pop_gallery.setCompoundDrawables(null,null,drawable,null);
       }
    
    
       //设置popWindow的背景----不要设置  会透视。。。
       public void setBg_popup() {
           WindowManager.LayoutParams lp = getWindow().getAttributes();
           lp.alpha = 1.0f;
           getWindow().setAttributes(lp);
       }
    
       //图片筛选器,过滤无效图片
       private FilenameFilter getFileterImage(){
           FilenameFilter filenameFilter = new FilenameFilter() {
               @Override
               public boolean accept(File dir, String filename) {
                   if (filename.endsWith(".jpg")
                           || filename.endsWith(".png")
                           || filename.endsWith(".jpeg"))
                       return true;
                   return false;
               }
           };
           return filenameFilter;
       }
    

    点击放大的popupWIndow

    public class BigImagePopup extends PopupWindow {
        ImageView iv_big_picture;
    
        public BigImagePopup(Activity context) {
            View conentView = LayoutInflater.from(context).inflate(R.layout.view_bigpic, null);
            setContentView(conentView);
    
            LinearLayout linearLayout = (LinearLayout) conentView.findViewById(R.id.ll_picture);
            iv_big_picture = (ImageView) conentView.findViewById(R.id.iv_big_picture);
    
            linearLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                }
            });
            iv_big_picture.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                }
            });
            setAnimationStyle(R.style.big_popup_camera);
            setFocusable(true);
            setTouchable(true);
            setOutsideTouchable(true);
            ColorDrawable background = new ColorDrawable(0xffffff);
            setBackgroundDrawable(background);
            setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
            setHeight(LinearLayout.LayoutParams.MATCH_PARENT);
        }
    
        public void setUrl(String url){
            BitmapKit.loadLocalImage(iv_big_picture, url);
        }
    
        public void showAtDropDownCenter(View parent) {
            if (!isShowing()) {
                setAnimationStyle(R.style.big_popup_camera);
                showAtLocation(parent, Gravity.BOTTOM, 0, 0);
            } else {
                dismiss();
            }
        }
    }
    

    写个这样的博客都这么累。。。。。

    相关文章

      网友评论

        本文标题:Android自定义相册,查看手机图片

        本文链接:https://www.haomeiwen.com/subject/lblivttx.html