在做项目时经常会遇到图片选着,选择单张图片还好,但类似于微信发朋友圈时可以多图选择的时候,就有点手足无措。然后在网上看了很多类似的项目,也尝试过将他们用于自己的项目,比如 知乎开源图片选择库 Matisse 等。但对比之下,PictureSelector 对我这种小白来说是更不错的选择。文章来源:https://www.toymoban.com/news/detail-700280.html
- 如何引用
dependencies {
// PictureSelector 基础 (必须)
implementation 'io.github.lucksiege:pictureselector:v3.0.9'
// 图片压缩 (按需引入)
implementation 'io.github.lucksiege:compress:v3.0.9'
// 图片裁剪 (按需引入)
implementation 'io.github.lucksiege:ucrop:v3.0.9'
// 自定义相机 (按需引入)
implementation 'io.github.lucksiege:camerax:v3.0.9'
}
- 添加权限 (按需添加)
<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" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Android 11 使用相机,需要再AndroidManifest.xm 添加如下代码:
<queries package="${applicationId}">
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE">
</action>
</intent>
<intent>
<action android:name="android.media.action.ACTION_VIDEO_CAPTURE">
</action>
</intent>
</queries>
- 图片加载策略, 框架默认提供的是Glide, 在使用的过程中,Glide的版本太高或者太低都有可能造成在调用PictureSelector方法时闪退。 我用的都是目前的最新版本4.13.0
implementation 'com.github.bumptech.glide:glide:4.13.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'
/**
* 在项目中创建一个GlideEngine类
* Glide加载引擎
*/
public class GlideEngine implements ImageEngine {
/**
* 加载图片
*
* @param context 上下文
* @param url 资源url
* @param imageView 图片承载控件
*/
@Override
public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
if (!ActivityCompatHelper.assertValidRequest(context)) {
return;
}
Glide.with(context)
.load(url)
.into(imageView);
}
/**
* 加载指定url并返回bitmap
*
* @param context 上下文
* @param url 资源url
* @param maxWidth 资源最大加载尺寸
* @param maxHeight 资源最大加载尺寸
* @param call 回调接口
*/
@Override
public void loadImageBitmap(@NonNull Context context, @NonNull String url, int maxWidth, int maxHeight, OnCallbackListener<Bitmap> call) {
if (!ActivityCompatHelper.assertValidRequest(context)) {
return;
}
Glide.with(context)
.asBitmap()
.override(maxWidth, maxHeight)
.load(url)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
if (call != null) {
call.onCall(resource);
}
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (call != null) {
call.onCall(null);
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
/**
* 加载相册目录封面
*
* @param context 上下文
* @param url 图片路径
* @param imageView 承载图片ImageView
*/
@Override
public void loadAlbumCover(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
if (!ActivityCompatHelper.assertValidRequest(context)) {
return;
}
Glide.with(context)
.asBitmap()
.load(url)
.override(180, 180)
.sizeMultiplier(0.5f)
.transform(new CenterCrop(), new RoundedCorners(8))
.placeholder(R.drawable.ps_image_placeholder)
.into(imageView);
}
/**
* 加载图片列表图片
*
* @param context 上下文
* @param url 图片路径
* @param imageView 承载图片ImageView
*/
@Override
public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
if (!ActivityCompatHelper.assertValidRequest(context)) {
return;
}
Glide.with(context)
.load(url)
.override(200, 200)
.centerCrop()
.placeholder(R.drawable.ps_image_placeholder)
.into(imageView);
}
@Override
public void pauseRequests(Context context) {
Glide.with(context).pauseRequests();
}
@Override
public void resumeRequests(Context context) {
Glide.with(context).resumeRequests();
}
private GlideEngine() {
}
private static GlideEngine instance;
public static GlideEngine createGlideEngine() {
if (null == instance) {
synchronized (GlideEngine.class) {
if (null == instance) {
instance = new GlideEngine();
}
}
}
return instance;
}
}
- 了解一下3.0版本的各个api的使用, 与2.0版本还是有蛮大区别的, 根据自己需求设置
.setSelectorUIStyle(); 设置相册主题
.setLanguage(); 设置相册语言
.setImageEngine(); 设置相册图片加载引擎
.setCompressEngine(); 设置相册压缩引擎
.setCropEngine(); 设置相册裁剪引擎
.setSandboxFileEngine(); 设置相册沙盒目录拷贝引擎
.setOriginalFileEngine(); 设置相册图片原图处理引擎
.setExtendLoaderEngine(); 设置相册数据源加载引擎
.setCameraInterceptListener(); 拦截相机事件,实现自定义相机
.setEditMediaInterceptListener(); 拦截资源编辑事件,实现自定义编辑
.setPermissionsInterceptListener(); 拦截相册权限处理事件,实现自定义权限
.setSelectLimitTipsListener();拦截选择限制事件,可实现自定义提示
.setSelectFilterListener();拦截不支持的选择项
.isCameraForegroundService(); 拍照时是否开启一个前台服务
.setRequestedOrientation(); 设置屏幕旋转方向
.setSelectedData(); 相册已选数据
.setRecyclerAnimationMode(); 相册列表动画效果
.setImageSpanCount(); 相册列表每行显示个数
.isDisplayCamera(); 是否显示相机入口
.isPageStrategy(); 是否开启分页模式
.selectionMode(); 单选或是多选
.setMaxSelectNum(); 图片最大选择数量
.setMinSelectNum(); 图片最小选择数量
.setMaxVideoSelectNum(); 视频最大选择数量
.setMinVideoSelectNum(); 视频最小选择数量
.setRecordVideoMaxSecond(); 视频录制最大时长
.setRecordVideoMinSecond(); 视频录制最小时长
.setFilterVideoMaxSecond(); 过滤视频最大时长
.setFilterVideoMinSecond(); 过滤视频最小时长
.setSelectMaxDurationSecond(); 选择最大时长视频或音频
.setSelectMinDurationSecond(); 选择最小时长视频或音频
.setVideoQuality(); 系统相机录制视频质量
.isQuickCapture(); 使用系统摄像机录制后,是否支持使用系统播放器立即播放视频
.isPreviewAudio(); 是否支持音频预览
.isPreviewImage(); 是否支持预览图片
.isPreviewVideo(); 是否支持预览视频
.isPreviewFullScreenMode(); 预览点击全屏效果
.isEmptyResultReturn(); 支持未选择返回
.isWithSelectVideoImage(); 是否支持视频图片同选
.isSelectZoomAnim(); 选择缩略图缩放效果
.isOpenClickSound(); 是否开启点击音效
.isCameraAroundState(); 是否开启前置摄像头;系统相机 只支持部分机型
.isCameraRotateImage(); 拍照是否纠正旋转图片
.isGif(); 是否显示gif文件
.isWebp(); 是否显示webp文件
.isBmp(); 是否显示bmp文件
.isHidePreviewDownload(); 是否隐藏预览下载功能
.isAutoScalePreviewImage(); 预览图片自动放大充满屏幕
.setOfAllCameraType(); isWithSelectVideoImage模式下相机优先使用权
.isMaxSelectEnabledMask(); 达到最大选择数是否开启禁选蒙层
.isSyncCover(); isPageModel模式下是否强制同步封面,默认false
.isAutomaticTitleRecyclerTop(); 点击相册标题是否快速回到第一项
.isFastSlidingSelect(); 快速滑动选择
.isDirectReturnSingle(); 单选时是否立即返回
.setCameraImageFormat(); 拍照图片输出格式
.setCameraImageFormatForQ(); 拍照图片输出格式,Android Q以上
.setCameraVideoFormat(); 拍照视频输出格式
.setCameraVideoFormatForQ(); 拍照视频输出格式,Android Q以上
.setOutputCameraDir(); 使用相机输出路径
.setOutputAudioDir();使用录音输出路径
.setOutputCameraImageFileName(); 图片输出文件名
.setOutputCameraVideoFileName(); 视频输出文件名
.setOutputAudioFileName(); 录音输出文件名
.setQuerySandboxDir(); 查询指定目录下的资源
.isOnlyObtainSandboxDir(); 是否只查询指定目录下的资源
.setFilterMaxFileSize(); 过滤最大文件
.setFilterMinFileSize(); 过滤最小文件
.setSelectMaxFileSize(); 最大可选文件大小
.setSelectMinFileSize(); 最小可选文件大小
.setQueryOnlyMimeType(); 查询指定文件类型
.setSkipCropMimeType(); 跳过不需要裁剪的类型
- 最后差不多就可以开始用了,建议大家把源码下下来看看作者是怎么用的
// 进入相册
PictureSelector.create(this)
.openGallery(SelectMimeType.ofImage())
.setImageEngine(GlideEngine.createGlideEngine()) // 这里就是设置图片加载引擎
.setMaxSelectNum(maxSelectNum)
.setSelectedData(adapter.getData()) // 设置已被选中的数据
.forResult(PictureConfig.CHOOSE_REQUEST);
/**
* 图片选择器回调
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PictureConfig.CHOOSE_REQUEST || requestCode == PictureConfig.REQUEST_CAMERA) {
ArrayList<LocalMedia> result = PictureSelector.obtainSelectorList(data);
analyticalSelectResults(result);
}
} else if (resultCode == RESULT_CANCELED) {
Log.i("TAG", "onActivityResult PictureSelector Cancel");
}
}
/**
* 处理选择结果
*
* @param result
*/
private void analyticalSelectResults(ArrayList<LocalMedia> result) {
for (LocalMedia media : result) {
if (media.getWidth() == 0 || media.getHeight() == 0) {
if (PictureMimeType.isHasImage(media.getMimeType())) {
MediaExtraInfo imageExtraInfo = MediaUtils.getImageSize(this, media.getPath());
media.setWidth(imageExtraInfo.getWidth());
media.setHeight(imageExtraInfo.getHeight());
} else if (PictureMimeType.isHasVideo(media.getMimeType())) {
MediaExtraInfo videoExtraInfo = MediaUtils.getVideoSize(this, media.getPath());
media.setWidth(videoExtraInfo.getWidth());
media.setHeight(videoExtraInfo.getHeight());
}
}
// Log.i(TAG, "文件名: " + media.getFileName());
// Log.i(TAG, "是否压缩:" + media.isCompressed());
// Log.i(TAG, "压缩:" + media.getCompressPath());
// Log.i(TAG, "初始路径:" + media.getPath());
// Log.i(TAG, "绝对路径:" + media.getRealPath());
// Log.i(TAG, "是否裁剪:" + media.isCut());
// Log.i(TAG, "裁剪:" + media.getCutPath());
// Log.i(TAG, "是否开启原图:" + media.isOriginal());
// Log.i(TAG, "原图路径:" + media.getOriginalPath());
// Log.i(TAG, "沙盒路径:" + media.getSandboxPath());
// Log.i(TAG, "水印路径:" + media.getWatermarkPath());
// Log.i(TAG, "视频缩略图:" + media.getVideoThumbnailPath());
// Log.i(TAG, "原始宽高: " + media.getWidth() + "x" + media.getHeight());
// Log.i(TAG, "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight());
// Log.i(TAG, "文件大小: " + media.getSize());
mImageList.add(new File(media.getRealPath())); // 接收已选图片地址,用于接口上传图片
}
}
把源码下载下来,看看demo是怎么写的。
参考文章:图片选择器:PictureSelector文章来源地址https://www.toymoban.com/news/detail-700280.html
到了这里,关于Android 仿微信图片选择器 PictureSelector3.0 的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!