android之图片选择器ImageSelector的使用

Posted kaolagirl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android之图片选择器ImageSelector的使用相关的知识,希望对你有一定的参考价值。

一.ImageSelector是什么?

android图片选择器,仿微信的图片选择器的样式和效果。支持图片的单选、限数量的多选和不限数量的多选。支持图片预览和图片文件夹的切换。支持在选择图片时调用相机拍照,也支持不用打开相册直接调用相机拍照。GitHub

二. ImageSelector方法

ImageSelector支持图片的单选、限数量的多选和不限数量的多选。还可以设置是否使用相机、是否剪切图片等配置。ImageSelector提供了统一的调起相册的方法。

// 单选
ImageSelector.builder()
.useCamera(true) // 设置是否使用拍照
.setSingle(true) //设置是否单选
.canPreview(true) //是否可以预览图片,默认为true
.start(this, REQUEST_CODE); // 打开相册

// 限数量的多选(比如最多9张)
ImageSelector.builder()
.useCamera(true) // 设置是否使用拍照
.setSingle(false) //设置是否单选
.setMaxSelectCount(9) // 图片的最大选择数量,小于等于0时,不限数量。
.setSelected(selected) // 把已选的图片传入默认选中。
.canPreview(true) //是否可以预览图片,默认为true
.start(this, REQUEST_CODE); // 打开相册

// 不限数量的多选
ImageSelector.builder()
.useCamera(true) // 设置是否使用拍照
.setSingle(false) //设置是否单选
.setMaxSelectCount(0) // 图片的最大选择数量,小于等于0时,不限数量。
.setSelected(selected) // 把已选的图片传入默认选中。
.canPreview(true) //是否可以预览图片,默认为true
.start(this, REQUEST_CODE); // 打开相册

// 单选并剪裁
ImageSelector.builder()
.useCamera(true) // 设置是否使用拍照
.setCrop(true) // 设置是否使用图片剪切功能。
.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
.setSingle(true) //设置是否单选
.canPreview(true) //是否可以预览图片,默认为true
.start(this, REQUEST_CODE); // 打开相册

// 仅拍照
ImageSelector.builder()
.onlyTakePhoto(true) // 仅拍照,不打开相册
.start(this, REQUEST_CODE);

// 拍照并剪裁
ImageSelector.builder()
.setCrop(true) // 设置是否使用图片剪切功能。
.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
.onlyTakePhoto(true) // 仅拍照,不打开相册
.start(this, REQUEST_CODE);

三. 使用步骤

1. 引入依赖
    implementation 'com.github.donkingliang:ImageSelector:2.2.1'
2.配置AndroidManifest.xml
//储存卡的读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//调用相机权限
<uses-permission android:name="android.permission.CAMERA" />

//图片选择Activity
<activity android:name="com.donkingliang.imageselector.ImageSelectorActivity"
	//去掉Activity的ActionBar。
	//使用者可以根据自己的项目去配置,不一定要这样写,只要让Activity的ActionBar去掉就可以了。
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    //横竖屏切换处理。
    //如果要支持横竖屏切换,一定要加上这句,否则在切换横竖屏的时候会发生异常。
    android:configChanges="orientation|keyboardHidden|screenSize"/>
    
//图片预览Activity
<activity android:name="com.donkingliang.imageselector.PreviewActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    android:configChanges="orientation|keyboardHidden|screenSize"/>

//图片剪切Activity
<activity
    android:name="com.donkingliang.imageselector.ClipImageActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

<!-- Android 7.0 文件共享配置,1.7.0之前必须配置,1.7.0后不需要 -->
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

在res/xml文件夹下创建file_paths.xml文件(名字可以自己定义)

<?xml version="1.0" encoding="utf-8"?>
<paths>

    <!-- 这个是保存拍照图片的路径,必须配置。 -->
    <external-path
        name="images"
        path="Pictures" />
</paths>
3.使用

我这个使用到相机拍照和 限数量的多选两个方法

  /**
     * todo 点击事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.uploadImg:  //打开弹窗(上传图片方式选择)
                createPopupWindow();
                break;
            //拍照上传
            case R.id.camera_btn:
                popupWindow.dismiss();
                //6.0才用动态权限
                if (Build.VERSION.SDK_INT >= 23) {
                    checkCameraPermission();
                }
                break;
            //从相册中选择
            case R.id.pic_btn:
                popupWindow.dismiss();
                //6.0才用动态权限
                if (Build.VERSION.SDK_INT >= 23) {
                    checkPicturePermission();
                }
                break;
        }
    }
    
 //todo 使用相机拍摄功能的权限检查并设置
    private void checkCameraPermission() {
        List<String> permissionList = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++) {
            if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(permissions[i]);
            }
        }
        if (permissionList.size() <= 0) {
            //说明权限都已经通过,可以做你想做的事情去(调起相机拍摄)
            
              使用ImageSelector相机拍照功能  /
            ImageSelector.builder()
                    .onlyTakePhoto(true)  // 仅拍照,不打开相册
                    .start(this, REQUEST_CODE);
                    
        } else {
            //对存在的未允许的权限进行申请
            ActivityCompat.requestPermissions(this, permissions, TAKE_PHOTO_PERMISSION_REQUEST_CODE);
        }
    }

    //todo 使用相册功能的权限检查并设置
    private void checkPicturePermission() {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            // 申请读写内存卡内容的权限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_SDCARD_PERMISSION_REQUEST_CODE);
        }else{
        
  限数量的多选(比如最多5张)   /
            ImageSelector.builder()
                    .useCamera(true) // 设置是否使用拍照
                    .setSingle(false)  //设置是否单选
                    .canPreview(false) //是否可以预览图片,默认为true
                    .setMaxSelectCount(5-imageList.size()) // 图片的最大选择数量,小于等于0时,不限数量。
                    .start(this, REQUEST_CODE); // 打开相册
        }
    }

/**
     * todo onRequestPermissionsResult 对用户权限授予结果处理
     * @param requestCode 权限要求码,即我们申请权限时传入的常量
     * @param permissions  保存权限名称的 String 数组,可以同时申请一个以上的权限
     * @param grantResults 每一个申请的权限的用户处理结果数组(是否授权)
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case TAKE_PHOTO_PERMISSION_REQUEST_CODE:
                boolean haspermission = false;
                for(int i=0;i<grantResults.length;i++){
                    if (grantResults[i] == -1){
                        haspermission = true;
                    }
                }
                if(haspermission){
                    //跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
                    permissionDialog();
                }else{
                 //全部权限通过,可以进行下一步操作(调起相机拍摄)
//                 openCamera();
                    ImageSelector.builder()
                            .onlyTakePhoto(true)  // 仅拍照,不打开相册
                            .start(this, REQUEST_CODE);
                }
                break;
            case WRITE_SDCARD_PERMISSION_REQUEST_CODE:
                if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                }else{
                    ToolUtils.midToast(this,"读内存卡内容权限被拒绝",1000);
                }
                break;
        }
    }

/**
     * todo onActivityResult 对拍照、相册选择图片的返回结果进行处理
     * @param requestCode 返回码,用于确定是哪个 Activity 返回的数据
     * @param resultCode 返回结果,一般如果操作成功返回的是 RESULT_OK
     * @param data 返回对应 activity 返回的数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case REQUEST_CODE:
                if(data !=null){
                    //获取选择器返回的数据 wang 7/23
                    ArrayList<String> images = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT);
                    /**是否是来自于相机拍照的图片,
                     * 只有本次调用相机拍出来的照片,返回时才为true。当为true时,图片返回的结果有且只有一张图片。
                     */
                    Boolean isCameraImage = data.getBooleanExtra(ImageSelector.IS_CAMERA_IMAGE,false);
                    getFile(images);
                }
                break;
        }
    }

 /**
     * todo Luban 压缩图片并上传
     * @param images
     * @author wang 2021/7/23
     */
    private void getFile(List<String> images) {
        Luban.with(this)
                .load(images)                     // 传入要压缩的图片
                .setCompressListener(new OnCompressListener() { // 设置回调

                    @Override
                    public void onStart() {
                        // 压缩开始前调用,可以在方法内启动 loading UI
                    }

                    @Override
                    public void onSuccess(File file) {
                        // 压缩成功后调用上传图片接口,File是压缩后的图片文件
                        upLoadImg(file.getPath());
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }
                }).launch();
    }

 /**
     * todo 上传图片(api)
     * @param imgString 压缩后的图片路径 (字符串)
     */
    private void upLoadImg(String imgString) {
      //调用后台接口上传图片
    }
4.效果图

以上是关于android之图片选择器ImageSelector的使用的主要内容,如果未能解决你的问题,请参考以下文章

andriod 图片选择器

仿QQ图片选择器--Android

Android图片选择器 多选框架

Android图片选择器

Android_性能优化之ViewPager加载成百上千高清大图oom解决方案

片段中的Android选择器意图到图片照片