2022

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

2017-01-01  本文已影响0人  Android绝世小菜鸟

最近因为公司需求需要做一个自定义的相册,因为手机自带的相册没有这种可以选取多张图片的功能,先上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();
        }
    }
}

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

上一篇 下一篇

猜你喜欢

热点阅读