Matisse 是知乎最近开源的一款 Android 图片/视频选择器。
GitHub地址:https://github.com/zhihu/Matisse
- 可以在 Activity 或者 Fragment 使用
- 可以选择JPEG, PNG, GIF 类型的图片,也支持选择 MPEG, MP4等格式的视频
- 可以应用在不同的主题,包括 Matisse 两套内置主题和自定义主题
- 支持不同的图片加载库,目前支持 Glide 和 Picasso。
- 支持自定义筛选规则
先看下知乎的效果图:
ZhihuStyle | Dracula Style | Preview |
下面我们就开始使用一下Matisse:
1、依赖配置
在bulid.gradle文件中添加依赖:
compile 'com.zhihu.android:matisse:0.5.0-alpha2'
另外这些依赖也要添加(可根据提示添加相应的依赖):
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:support-annotations:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
2.添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Android 6.0之后需要动态获取一些涉及隐私的权限(原demo使用的是RxJava获取权限,这里使用了另外一种方式):
/**
* android 6.0之后需要动态获取权限
*/
@TargetApi(23)
private void getPersimmions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ArrayList<String> permissions = new ArrayList<String>();
/**
* 读写权限非必要权限(建议授予)只会申请一次,用户同意或者禁止,只会弹一次
*/
if (addPermission(permissions, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
permissionInfo += "Manifest.permission.WRITE_EXTERNAL_STORAGE Deny \n";
}
if (addPermission(permissions, Manifest.permission.READ_EXTERNAL_STORAGE)) {
permissionInfo += "Manifest.permission.READ_EXTERNAL_STORAGE Deny \n";
}
if (permissions.size() > 0) {
requestPermissions(permissions.toArray(new String[permissions.size()]), SDK_PERMISSION_REQUEST);
}
}
}
@TargetApi(23)
private boolean addPermission(ArrayList<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { // 如果应用没有获得对应权限,则添加到列表中,准备批量申请
if (shouldShowRequestPermissionRationale(permission)){
return true;
}else{
permissionsList.add(permission);
return false;
}
}else{
return true;
}
}
@TargetApi(23)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// TODO Auto-generated method stub
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
3.ProGuard
如果使用Glide作为图片加载开源库
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
如果使用Picasso作为图片加载开源库
-dontwarn com.squareup.okhttp.**
4.代码使用
知乎主题:
Matisse.from(MainActivity.this)
.choose(MimeType.ofAll())
.countable(true)
.maxSelectable(9)
.addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
.gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
.thumbnailScale(0.85f)
.imageEngine(new GlideEngine())
.forResult(REQUEST_CODE_CHOOSE);
Dracula主题:
Matisse.from(MainActivity.this)
.choose(MimeType.of(MimeType.JPEG, MimeType.PNG))
.theme(R.style.Matisse_Dracula)
.countable(false)
.maxSelectable(9)
.imageEngine(new PicassoEngine())
.forResult(REQUEST_CODE_CHOOSE);
自定义主题:
Matisse.from(MainActivity.this)
.choose(MimeType.ofVideo())
.theme(R.style.Matisse_Custom)
.countable(false)
.maxSelectable(9)
.forResult(REQUEST_CODE_CHOOSE);
需要在colors,styles文件下设置相关的属性。
colors | styles |
效果如下:
处理结果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {
mAdapter.setData(Matisse.obtainResult(data));
}
}
5.方法参数解析
choose(Set mimeType): 选择图片、视频类型。支持jpg,jpeg,png,gif ,mpeg, mp4, mov, 3gpp, 3pp2, mkv, webm, ts, avi。
theme(@StyleRes int themeId):设置主题风格。
countable(boolean countable):用于判断是否标记选中项数量。返回true则从 1 开始计数。默认是false。
maxSelectable(int maxSelectable):最大可选中项数
addFilter(Filter filter):添加过滤条件。我们可以通过集成Filter抽象类实现对应的过滤条件来对图片进行筛选,可以添加多个Filter。
例如这里设置了gif类型的图片Filter: new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K):长宽不小于320dpx,且大小不超过 5M 的gif文件。
gridExpectedSize(int size):设置要求展示的图片大小值
thumbnailScale(float scale):图片缩略值。范围在(0.0, 1.0],默认值是0.5。
restrictOrientation(int orientation):设置屏幕方向。横/竖屏 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
imageEngine(ImageEngine imageEngine):图片加载接口。目前支持GlideEngine,PicassoEngine。(Glide全包含Picasso支持的功能,而且Picasso不支持Gif)
代码中知乎主题下使用的是 GlideEngine ,支持Gif类型的文件。
代码中Dracula主题下使用的是 PicassoEngine ,Picasso不支持Gif类型的文件。
6.类分析
类名 | 描述 |
ImageEngine | 图片加载接口,方便后面根据Glide和Picasso分别实现 |
GlideEngine | Glide实现ImageEngine |
PicassoEngine | Picasso实现ImageEngine |
Filter | 过滤条件抽象类,我们可以通过集成Filter实现对应的过滤条件来对图片进行筛选,可以添加多个Filter,具体参考官方Demo中的GifSizeFilter |
Album | 相册Entity |
CaptureStrategy | 拍照相关,媒体处理authority |
IncapableCause | 信息处理,toast和dialog |
Item | 选择媒体界面的Item |
SelectionSpec | 选择参数类 |
AlbumLoader | 相册CursorLoader |
AlbumMediaLoader | 图片和视频CursorLoader |
AlbumCollection | AlbumLoader回调 |
AlbumMediaCollection | AlbumMediaLoader回调 |
SelectedItemCollection | 被选中项集合 |
internal/ui包 | 界面显示的Adapter,自定义视图,Fragment和Activity |
internal/utils包 | 工具类 |
MatisseActivity | 关键类,执行选择媒体操作的时候展示出来的Activity |
Matisse | 开源库的入口和出口,用来传递Activity和Fragment,创建SelectionSpecBuilder和返回结果 |
MimeType | 媒体类型 |
SelectionSpecBuilder | Build构造类,用来传递参数 |