前言
我们在做App的时候很多需求都要选择图片
比如说:
- 上传头像
- 上传朋友圈
- 发送图片
- 内容编辑插入图片
我们也可以使用系统的组件来完成我们的需求
Intent toGallery = new Intent(Intent.ACTION_GET_CONTENT);
toGallery.setType("image/*");
toGallery.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(toGallery, REQUEST_GALLERY);
@Override//返回选择照片的Uri
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri uri = data.getData();
}
通过这种方式打开系统中支持文件选择的Activity,选取我们需要的照片,然而这种方式并不是特别美观,很多时候不能达到我们想要的效果,而且开源盛世的今天,有许多选择库提供我们选择,使用也非常简单!
今天给大家介绍知乎开源的选择图片的库——Matisse效果预览
分别是 白天模式(蓝色主题)、夜间模式(暗色主题)、预览效果图
Github地址:
https://github.com/zhihu/Matisse
优点
- 简单容易上手
- 支持日夜间模式,可以自定义主题
- 自定义选中图片的最大数
- JPEG, PNG, GIF 图片类型的显示
- 支持有序选择图片,也即选择图片的时候会有 1, 2, 3, 4… 样式的 CheckBox;
- 支持自定义筛选,完全自定义筛选规则
- 可以定义图片缩略图的缩放比例。
- 支持横竖屏。Matisse 做了状态保存的工作
- 支持不同的图片加载库,目前支持 Glide 和 Picasso
如何使用
第一步
添加依赖
Gradle:
repositories {
jcenter()
}
dependencies {
compile 'com.zhihu.android:matisse:0.5.0-alpha4'
compile 'com.github.bumptech.glide:glide:3.7.0'
}
也要添加上glide的包,图片加载器,用glide演示
第二步
Matiss须要添加两个权限,如果是6.0+的版本,须要申请运行时权限,否则报错
如果你使用 Glide 作为你的图片加载引擎,请添加 Glide 的 README 上所说的规则,以及添加额外的规则:
-dontwarn com.squareup.picasso.**
如果你使用 Picasso 作为你的图片加载引擎,请添加 Picasso 的 README 上所说的规则,以及添加额外的规则:
-dontwarn com.bumptech.glide.**
第三步
如果你不需要点击拍照,而且也对过滤没有要求的话就可以直接使用了
跳转到MatisseActivity从你当前的Activity或者Fragment
基本使用方式
1.定义常量
private static final int REQUEST_CODE_CHOOSE = 23;//定义请求码常量
2.启动MatisseActivity
Matisse
.from(MainActivity.this)
.choose(MimeType.allOf())//照片视频全部显示
.countable(true)//有序选择图片
.maxSelectable(9)//最大选择数量为9
.gridExpectedSize(120)//图片显示表格的大小getResources()
.getDimensionPixelSize(R.dimen.grid_expected_size)
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)//图像选择和预览活动所需的方向。
.thumbnailScale(0.85f)//缩放比例
.theme(R.style.Matisse_Zhihu)//主题 暗色主题 R.style.Matisse_Dracula
.imageEngine(new GlideEngine())//加载方式
.forResult(REQUEST_CODE_CHOOSE);//请求码
3、接收选择的结果
List mSelected;
@Override //接收返回的地址
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {
mSelected = Matisse.obtainResult(data);
Log.d("Matisse", "mSelected: " + mSelected);
}
}
注意事项
关于拍照
想要使用拍照功能的话,必须要有一个Fileprovider
在Android Manifest当中的Application节点下添加FileProvider
然后在Res文件下创建xml文件夹,然后创建filepaths.xml
authorites是你项目的包名 + fileprovider
filepaths的代码如下:
如果对FileProvider不了解可以看一下这篇文章 FileProvider建立文件分享
这里的authority要和Manifest当中保持一致
在启动Matisse当中添加如下代码
.capture(true) //是否提供拍照功能
.captureStrategy(new CaptureStrategy(true,String authority))//存储到哪里
关于过滤器
想要使用过滤器的话,必须要自定义过滤器,继承Filter。
这里我已经定义好了,直接用就可以,要是有特别的需求自己实现,可以添加多个过滤器
class GifSizeFilter extends Filter {
private int mMinWidth;
private int mMinHeight;
private int mMaxSize;
GifSizeFilter(int minWidth, int minHeight, int maxSizeInBytes) {
mMinWidth = minWidth;
mMinHeight = minHeight;
mMaxSize = maxSizeInBytes;
}
@Override
public Set constraintTypes() {
return new HashSet() {{
add(MimeType.GIF);
add(MimeType.MP4);
}};
}
@Override
public IncapableCause filter(Context context, Item item) {
if (!needFiltering(context, item))
return null;
Point size = PhotoMetadataUtils.getBitmapBound(context.getContentResolver(), item.getContentUri());
if (size.x < mMinWidth || size.y < mMinHeight || item.size > mMaxSize) {
return new IncapableCause(IncapableCause.DIALOG, context.getString(R.string.error_gif, mMinWidth,
String.valueOf(PhotoMetadataUtils.getSizeInMB(mMaxSize))));
}
return null;
}
}
定义好之后在启动MatisseActivity的方法中添加如下代码
.addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
关于Api
方法名 | 描述 | 参数 |
---|---|---|
showSingleMediaType() | 仅仅显示一种媒体类型 | Boolean |
from() | 传递当前的Activity或者fragment | MainActivity.this |
choose() | 显示图片的类型 | MimeType.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF) 或者MimeType.ofAll() |
countable() | 是否有序选择图片 | Boolean |
maxSelectable() | 最大的选择数量 | int类型 多少都可以 |
addFilter() | 添加过滤器 | new GifSizeFilter(320, 320, 5 Filter.K Filter.K),自己重写过滤器 |
gridExpectedSize() | 每个图片方格的大小 | 120dp |
restrictOrientation() | 设置图像选择和预览活动所需的方向 | ActivityInfo.SCREEN_ORIENTATION_PORTRAIT或者 |
thumnailScale() | 缩放比例 | 0.1-1之间,一般0.85f |
imageEngine() | 使用图片的加载方式 | new GlideEngine()或者new PicassoEngine() |
theme() | 主题的设置 | R.style.Matisse_Zhihu 或者 R.style.Matisse_Dracula |
forResult() | 请求码 | REQUEST_CODE_CHOOSE |
包含的类
类名 | 描述 |
---|---|
ImageEngine | 图片加载接口,方便后面根据Glide和Picasso分别实现 |
GlideEngine | Glide实现ImageEngine |
PicassoEngine | Picasso实现ImageEngine |
Filter | 过滤条件抽象类,我们可以通过集成Filter实现对应的过滤条件来对图片进行筛选,可以添加多个Filter |
Album | 相册Entity |
CaptureStrategy | 拍照相关,媒体处理authority |
IncapableCause | 信息处理,toast和dialog |
Item | 选择媒体界面的Item |
SelectionSpec | 选择参数类 |
AlbumLoader | 相册CursorLoader |
AlbumMediaLoader | 图片和视频CursorLoader |
AlbumMediaCollection | AlbumMediaLoader回调 |
SelectedItemCollection | 被选中项集合 |
internal/ui包 | 界面显示的Adapter,自定义视图,Fragment和Activity |
internal/utils包 | 工具类 |
MatisseActivity | 关键类,执行选择媒体操作的时候展示出来的Activity |
Matisse | 开源库的入口和出口,用来传递Activity和Fragment,创建SelectionSpecBuilder和返回结果 |
MimeType | 媒体类型 |
SelectionSpecBuilder | Build构造类,用来传递参数 |