效果图:

就目前效果图来看,好像也没什么毛病哈,其实我这个集成的过程是有点坎坷的。
而且,功能也不算是很齐全吧…主要体现在以下几个点

  • 没有回调之后的预览
  • 选择之后不能删除已选
  • 已选择的图片再次选择不能带过去
  • 剪裁
  • 压缩
  • 权限
  • Glide版本过低

但是,也是有特点的

  • MD风格
  • 白天模式和夜间模式

其他与同类相比也真的没什么了,唯一背书 就是知乎团队出的呗。。
相比之下,昨天出的Android 选择图片、上传图片之PictureSelector就更加友好和人性化了。

下面来说说集成遇到的问题以及解决方案。

gayhub:https://github.com/zhihu/Matisse

集成

Gradle:

repositories {jcenter()
}dependencies {compile 'com.zhihu.android:matisse:0.4.3'
}

releases最新是v0.5.0-beta3的,本文还是基于官方文档0.4.3的版本

你以为这样就可以使用了吗,nonono,权限需要动态获取,你还需要RxPermissions或者其他权限库,或者自己封装

compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'

这就完了吗,no,你还需要rxjava

compile "io.reactivex.rxjava2:rxjava:2.1.9"

现在总可以了吧,依然nonono,如果你项目集成了Glide,还是会报错,我在用的Glide版本是4.6.1的,Matisse中集成的是3.7.0的,是有区别的,具体你可以看这里 带你全面了解Glide 4的用法,你也可以用Picasso。

会报异常

java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load

解决方案就是重新自定义图片加载方式GlideEngine,具体可以看这里Matisse 与 Glide – java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load。

到这里你以为就ok了吗,还是nonono,还是会报异常,因为两个版本会冲突啊

java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper

解决方案看这里java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper

Matisse:爱我你怕了吗

终于可以使用了,哇的哭出声

使用

你以为集成都这么坎坷了,使用应该很方便吧,no啊大胸弟,
虽然集成之前我看到150+的Issues有点头皮发麻,果然没让我失望,坎坷的路还长着呢。

最快的方式集成第三方有两种,1.看官方文档,2.看例子。

你以为从sample中copy copy代码,导下包就能跑起来了吗,nonono

选择器不光是有图片的吧,你可能还有gif和视频啊,所以在配置的时候你要选择一个type啊

sample是这样的

Matisse.from(SampleActivity.this).choose(MimeType.ofAll(), false)...

源码实际上是这样的

 public SelectionSpecBuilder choose(Set<MimeType> mimeType) {return new SelectionSpecBuilder(this, mimeType);}

所以,你的应该是这样的

Matisse.from(MainActivity.this).choose(MimeType.allOf())...

没有boolean类型参数,而且也不是ofAll了,而是allOf

上面是把所有的都列出来,那我如果只选图片怎么办呢

sample是这样的

Matisse.from(SampleActivity.this).choose(MimeType.ofImage())...

尼玛。。实际上MimeType这个枚举类中根本就没有ofImage

所以你的应该是这样的

Matisse.from(MainActivity.this).choose(MimeType.of(MimeType.JPEG))...

所以,刺不刺激?

对了,你如果要用最新版本,比如v0.5.0-beta3,注意去掉前面的v。

然后,你可以跑起来了,也不会报错了,仿佛一切都ok的样子(翻译一下:其实并没有,逃..)

遇到几个点还没有解决,也懒得深入研究了,我要回家过年,哼

  1. 拍照还是选择相册,没有处理
  2. 预览,选择图片的时候可以预览,但是回调之后并不行,没有处理
  3. onActivityResult回调之后的图片不能直接删除,没有处理
  4. 剪裁,没有处理
  5. 压缩,没有处理
  6. 哦对了,如果可以预览了,那还得可以保存图片呢,也没有处理,因为预览没有处理,哈哈哈嗝
  7. 已选择的图片,再次选择的时候带过去,没有处理

那有人就会说了,这么多没有的功能,或者文档没有介绍到的,不是可以自己去处理吗,这样岂不是定制化更高?比如筛选条件、主题…
emmm…
你说的对,但我不认同。哈哈哈

哦对了,选择图片的时候可以预览,看一下是什么样的

啊。。scaleType不对就不说了,可是你让我的toolbar兄弟如何自处?又要挨window爸爸的打了。。

哦对了,0.5的版本加了新功能,但是正式版还没有发布

最后,不要忘了加权限和FileProvider。
然后贴一下MainActivity的代码和gayhub的地址

package com.yechaoa.matissedemo;import android.Manifest;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;import com.bumptech.glide.Glide;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.internal.entity.CaptureStrategy;import java.util.List;import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private UriAdapter mAdapter;private static final int REQUEST_CODE_CHOOSE = 23;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.zhihu).setOnClickListener(this);findViewById(R.id.dracula).setOnClickListener(this);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);recyclerView.setLayoutManager(new GridLayoutManager(this, 3));recyclerView.setAdapter(mAdapter = new UriAdapter());}/*** 1 预览  2 已选择带过去  3 剪裁  4 压缩* <p>* 120 显示三列  100显示四列*/@Overridepublic void onClick(final View v) {RxPermissions rxPermissions = new RxPermissions(MainActivity.this);rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(new Observer<Boolean>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Boolean aBoolean) {if (aBoolean) {switch (v.getId()) {case R.id.zhihu:Matisse.from(MainActivity.this).choose(MimeType.allOf())//ofAll().theme(R.style.Matisse_Zhihu)//主题,夜间模式R.style.Matisse_Dracula.countable(true)//是否显示选中数字.capture(true)//是否提供拍照功能.captureStrategy(new CaptureStrategy(true, "com.zhihu.matisse.sample.fileprovider"))//存储地址.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 MyGlideEngine())//图片加载方式.forResult(REQUEST_CODE_CHOOSE);//请求码break;case R.id.dracula:Matisse.from(MainActivity.this).choose(MimeType.of(MimeType.JPEG))//ofImage().theme(R.style.Matisse_Dracula).countable(false).maxSelectable(9).imageEngine(new MyGlideEngine()).forResult(REQUEST_CODE_CHOOSE);break;}mAdapter.setData(null);} else {Toast.makeText(MainActivity.this, "权限被拒绝了..", Toast.LENGTH_LONG).show();}}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});}@Overrideprotected 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));}}private class UriAdapter extends RecyclerView.Adapter<UriAdapter.UriViewHolder> {private List<Uri> mUris;void setData(List<Uri> uris) {mUris = uris;notifyDataSetChanged();}@Overridepublic UriViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {return new UriViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.uri_item, parent, false));}@Overridepublic void onBindViewHolder(UriViewHolder holder, int position) {Glide.with(MainActivity.this).load(mUris.get(position)).into(holder.mImg);}@Overridepublic int getItemCount() {return mUris == null ? 0 : mUris.size();}class UriViewHolder extends RecyclerView.ViewHolder {private ImageView mImg;UriViewHolder(View contentView) {super(contentView);mImg = (ImageView) contentView.findViewById(R.id.img);}}}}

gayhub:https://github.com/yechaoa/MatisseDemo

Android 选择图片、上传图片之Matisse相关推荐

  1. Android 选择图片、上传图片之ImagePicker

    效果图: 后来又出了两篇,也可以看一下 Android 选择图片.上传图片之PictureSelector Android 选择图片.上传图片之Matisse 添加依赖: 选择图片:compile ' ...

  2. 微信开发php插件下载图片,微信开发之微信jsapi选择图片,上传图片,预览和下载图片方法...

    参数描述 appId公众号的唯一标识 应用id timestamp生成签名的时间戳 nonceStr生成签名的随机串 signature签名 上述表格中的四个参数是初始化调用微信jsapi的凭证,咱们 ...

  3. android选择图片或拍照开源项目,Android 开源照相和图片选择框架PictureSelector

    拍照或者相册选择图片并渲染到UI上,发现了一个更简单的三方框架来实现 -- PictureSelector.Github地址:https://github.com/LuckSiege/PictureS ...

  4. Android选择图片

    我的视频课程:<FFmpeg打造Android万能音频播放器> 距离上次更新博客都感觉是好久远的事了,不过不管过多久,有更新总是不错的.今天给大家带来一个自己写的获取Android手机相册 ...

  5. android 选择图片sdk,GitHub - XieZed/CameraSDK: Android多图选取,滤镜,贴纸,裁剪等类似美图秀秀的功能...

    非常实用的类似新浪微博的多图片选择工具 一.软件功能: 1.可以加载手机里面所有的图片 2.也可以根据相册文件夹选择图片 3.裁剪正方形图片 4.给图片加滤镜特效 5.给图片加贴纸功能 6.可以删除已 ...

  6. Android 调用相机APP获取拍照图片和从相册选择图片

    源码部分分析 Camera.java → 点我定位,注意研究1134行与2023行的两个方法. 通过源码可以发现,输出的图片有2个分支 如果你没有指定Intent里面的Extra参数,它就返回一个序列 ...

  7. Android实现拍照选择相册图片上传图片(多图片上传)功能

    安卓多图片上传代码 直接上代码 1.主程序入口XML文件 <?xml version="1.0" encoding="utf-8"?> <ma ...

  8. 【OkHttp】OkHttp 上传图片 ( 获取 SD 卡动态权限 | 跳转到相册界面选择图片 | 使用 OkHttp 上传图片文件 )

    OkHttp 系列文章目录 [OkHttp]OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) [OkHttp]Android 项目导入 OkHttp ( 配置依赖 | 配置 ...

  9. Android手机图片上传 选择不了本地照片 解决方案

    问题描述:在实现Android端向服务器上传图片过程中,本人采用的是Android4.4版本,最初选择图片的代码是这样写的: //        Intent intent = new Intent( ...

  10. android工程换背景图片,Android初学者:用知乎Matisse开源项目制作更换应用背景图片功能...

    前言 我搜索了下关于知乎Matisse的使用教程甚少,于是我就想着来做一个教程,这个教程是针对初学者的,因为我自己也是一个初学者,希望对各位刚刚接触Android开发的小伙伴有帮助! 关于Matiss ...

最新文章

  1. 普通(实例)方法和实例方法的定义和调用
  2. jquery实现点击改变背景色,点击其他恢复原来背景色,被点击的改变背景色
  3. JavaScript基础05-day07【条件运算符、运算符优先级、代码块、if语句】
  4. Java多线程(十)之ReentrantReadWriteLock深入分析
  5. 计算机画面的音乐素材,音效素材:高科技用户界面UI点触计算机数据分析全息音效合集...
  6. 【转】Qtcreator中常用快捷键和小技巧
  7. C#序列化和反序列化代码总结
  8. 数据结构 5-3-2 二叉树前序中序后序遍历非递归实现
  9. windows10 显示实时网速
  10. 《嵌入式 – GD32开发实战指南》第1章 开发环境搭建
  11. 虚拟主机和云服务器有什么区别,我们应该如何选择?
  12. Spark (一):大数据概述
  13. python程序输入两个整数、实现加减乘除_加减乘除
  14. 1128: mxh道歉记
  15. android ios mp4格式转换,爱思助手怎么转换视频格式 爱思助手将普通视频格式转换为mp4格式方法...
  16. (7)目标检测之CNN、ResNet用于目标3D检测框的回归估计、3D检测框绘制
  17. virtualbox 靶机无法获取IP地址
  18. Jupyter Notebooks学习分享
  19. 基于 NIOS-II 软核的流水灯
  20. DRF学习之短信验证的实现用户注册(十二)

热门文章

  1. 大数据——DBT:dbt集成数据质量监控插件elementary(生产环境篇)
  2. 大话卫星导航中的信号处理系列文章——目录
  3. 一个页面播放多个视频
  4. wamp中为何php文件需要下载,配置WAMP后,浏览器输入默认的php文件名都直接下载该文档...
  5. 你能猜出这是什么代码吗
  6. php unlink参数,PHP unlink()用法及代码示例
  7. 【后端】Nginx 体系
  8. 如何提高服务器网站访问速度,如何有效提升网站打开速度?
  9. 三国志战略版:北定中原剧本个性加点指引
  10. sklearn.neighbors常用API介绍