TakePhoto框架源码流程解析(二)

上一篇TakePhoto框架源码流程解析(一)地址,这一篇打算详细介绍下TakePhotoImpl的使用,毕竟是TakePhoto的核心类,所有的调用都会回调到这个类中,所以还是有必要学习下,对自己的编程能力还是有很大提升的。

在上一篇介绍到,当我们调用接口的某个方法时,都会走动态代理的TakePhotoInvocationHandlerinvoke方法,最后会回调到TakePhotoImpl的对应方法。 接下来继续看下下面几个常用方法的流程。


onPickMultiple

从相册选择多张图片,这个相册是自定义的一个相册,而不是系统相册,我们可以限制选择的图片数量,看下其实现:

@Override
public void onPickMultiple(int limit) {
    if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
    TUtils.startActivityForResult(contextWrap, new TIntentWap(IntentUtils.getPickMultipleIntent(contextWrap, limit), TConstant.RC_PICK_MULTIPLE));
}

首先判断TPermissionType的状态是否为TPermissionType.WAIT,表示在等待用户同意权限,如果在等待,就不会执行接下来的方法,否则接下来继续往下执行。下面一段封装了跳转页面的Intent实现,TIntentWap封装了一个IntentrequestCode,而Intent是由IntentUtils.getPickMultipleIntent获取的,看下实现

/**
 *  获取图片多选的Intent
 * @param limit 最多选择图片张数的限制
 * */
public static Intent getPickMultipleIntent(TContextWrap contextWrap, int limit){
    Intent intent = new Intent(contextWrap.getActivity(), AlbumSelectActivity.class);
    intent.putExtra(Constants.INTENT_EXTRA_LIMIT, limit>0? limit:1);
    return intent;
}

可以知道选择图片的ActivityAlbumSelectActivity,图片限制可以通过Constants.INTENT_EXTRA_LIMIT添加。图片选择完之后通过onActivityResult回调,通过requestCode可知道执行的对应的代码位置为:

.....
case TConstant.RC_PICK_MULTIPLE://多选图片返回结果
            if (resultCode == Activity.RESULT_OK && data != null) {
                ArrayList<Image> images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
                if (cropOptions != null) {
                    try {
                        onCrop(MultipleCrop.of(TUtils.convertImageToUri(contextWrap.getActivity(), images), contextWrap.getActivity(), fromType), cropOptions);
                    } catch (TException e) {
                        cropContinue(false);
                        e.printStackTrace();
                    }
                } else {
                    takeResult(TResult.of(TUtils.getTImagesWithImages(images, fromType)));
                }

            } else {
                listener.takeCancel();
            }
            break;

通过判断是否配置cropOptions ,来决定是否裁剪图片,否则执行takeResult

private void takeResult(final TResult result, final String... message) {
    if (null == compressConfig) {
        handleTakeCallBack(result, message);
    } else {
        if (showCompressDialog)
            wailLoadDialog = TUtils.showProgressDialog(contextWrap.getActivity(), contextWrap.getActivity().getResources().getString(R.string.tip_compress));

    ....................................

    }
}

takeResult中,通过判断是否压缩图片,来决定走那个回调,先来判断不压缩图片,压缩的部分后面单独讲。不压缩部分走handleTakeCallBack(result, message);方法

private void handleTakeCallBack(final TResult result, String... message) {
    if (message.length > 0) {
        listener.takeFail(result, message[0]);
    } else if (multipleCrop != null && multipleCrop.hasFailed) {
        listener.takeFail(result, contextWrap.getActivity().getResources().getString(R.string.msg_crop_failed));
    } else if (compressConfig != null) {
        boolean hasFailed = false;
        for (TImage image : result.getImages()) {
            if (image == null || !image.isCompressed()) {
                hasFailed = true;
                break;
            }
        }
        if (hasFailed) {
            listener.takeFail(result, contextWrap.getActivity().getString(R.string.msg_compress_failed));
        } else {
            listener.takeSuccess(result);
        }
    } else {
        listener.takeSuccess(result);
    }
    clearParams();
}

这个方法是去处理图片的结果,如果配置了multipleCropcompressConfig ,就去判断是否有裁剪失败或者有没有压缩的图片如果都不满足,才去执行listener.takeSuccess(result);方法,也就是我们在业务逻辑处理的takeSuccess方法。处理完之后会调用clearParams()清除配置的压缩裁剪拍照属性,所以我们下次调用之前要重新配置这些属性。onPickMultiple的流程介绍就这多了。


onPickMultipleWithCrop

它比onPickMultiple多了个裁剪功能,看下其裁剪实现

onCrop(MultipleCrop.of(TUtils.convertImageToUri(contextWrap.getActivity(), images), contextWrap.getActivity(), fromType), cropOptions);

裁剪会走这个流程,封装了一个MultipleCropcropOptionsTUtils.convertImageToUri里面兼容到7.0了。而onCrop可以通过配置,来使用自己的或者第三方的裁剪。


onPickFromDocuments, onPickFromGallery

这两个方法都是选择相片,一个是从文档,一个是从相册获取,两个方法都会走selectPicture,看下实现

private void selectPicture(int defaultIndex, boolean isCrop) {
    this.fromType = TImage.FromType.OTHER;
    if (takePhotoOptions != null && takePhotoOptions.isWithOwnGallery()) {
        onPickMultiple(1);
        return;
    }
    if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
    ArrayList<TIntentWap> intentWapList = new ArrayList<>();
    intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithDocuments(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_CROP : TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL));
    intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithGallery(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP : TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL));
    try {
        TUtils.sendIntentBySafely(contextWrap, intentWapList, defaultIndex, isCrop);
    } catch (TException e) {
        takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage());
        e.printStackTrace();
    }
}

如果我们是用自己的相册,就直接走onPickMultiple方法,否则在一个List里面封装两个intent,然后结合defaultIndex,来决定使用那个intentintent里面封装了选择相片的方式。


onPickFromGalleryWithCrop, onPickFromDocumentsWithCrop

上面两个方法的扩展,可以在选择完图片之后,再去裁剪图片。

onPickFromCapture, onPickFromCaptureWithCrop

这两个方法为去拍照和拍照并裁剪。这两个方法都会去将传进来的url适配到7.0。

if (Build.VERSION.SDK_INT >= 23) {
    this.tempUri = TUriParse.getTempUri(contextWrap.getActivity());
} else {
    this.tempUri = outPutUri;
}

然后调用TUtils.captureBySafely,来打开系统相机。最后调用onCrop裁剪相片。


最后

基本的使用就是这多了,接下来将会介绍下TakePhoto的压缩实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值