当前位置:   article > 正文

知乎 Matisse 源码解析,探究高效图片选择库的秘密_com.github.zhihu:matisse

com.github.zhihu:matisse

目录

  • 基本介绍
  • 整体的设计和实现流程
  • 资源文件夹的加载和展示
  • 主页图片墙的实现
  • 预览界面的实现
  • 总结

一、基本介绍


Matisse 是「知乎」开源的一款十分精美的本地图像和视频选择库。

Matisse 的代码写的相当的简洁、规范,很有学习的价值。

讲一下 Matisse 的一些优点:

  • 在 Activity 或 Fragment 都可以轻松的调用

  • 支持各种格式的图片和视频加载

  • 支持不同的样式,包括两种内置主题和自定义主题

  • 可以自定义文件的过滤规则

可以看到 Matisse 的可拓展性是非常强的,不仅可以自定义我们需要的主题,而且还可以按照需求来过滤出我们想要的文件,除此之外,Matisse 采用了建造者模式,使得我们可以通过链式调用的方式,配置各种各样的属性,使我们的图片选择更加灵活。

二、整体的设计和实现流程


在介绍 Matisse 的工作流程之前,我们先来看看几个比较重要的类,有助于我们后面的理解

类名 功能
Matisse 通过外部传入的 Activity 或 Fragment,以弱引用的形式进行保存,同时通过 from() 方法返回 SelectionCreator 进行各个参数的配置
SelectionCreator 通过建造者模式,链式配置我们需要的各种属性
MatisseActivity Matisse 首页的 Activity,将图片和视频进行展示

我们先从 Matisse 的使用入手,看看 Matisse 的工作流程。

Matisse.from(MainActivity.this)
        .choose(MimeType.allOf()) // 1、获取 SelectionCreator
        .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_UNSPECIFIED)
        .thumbnailScale(0.85f)
        .imageEngine(new GlideEngine()) // 2、配置各种各样的参数
        .forResult(REQUEST_CODE_CHOOSE); // 3、打开 MatisseActivity
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

上面的使用代码,我们以 Activity 为例,可以分成三部分来看

  • 将外部传入的 Activity 以弱引用的形式进行保存,然后调用 choose() 获取 SelectionCreator

  • 通过链式调用的方式,配置 SelectionCreator 的各种属性,如可选择的数量、缩略图的大小、加载图片的引擎等

  • 使用从第一步中传入的 Activity 调用 startActivityForResult(),并从外部传入请求码,以便到时候返回所选择图片的 List

具体的流程图如下:

以上便是 Matisse 的工作流程,接下来详细的分析下相关的类。有一点要先说明一下,我下面贴出的所有类中的源码并不是完整的代码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的「核心代码」。

Matisse
public final class Matisse {

    private final WeakReference<Activity> mContext;
    private final WeakReference<Fragment> mFragment;

    private Matisse(Activity activity, Fragment fragment) {
        mContext = new WeakReference<>(activity);
        mFragment = new WeakReference<>(fragment);
    }

    public static Matisse from(Activity activity) {
        return new Matisse(activity);
    }

    public static Matisse from(Fragment fragment) {
        return new Matisse(fragment);
    }

    /**
     *  在打开 MatisseActivity 的 Activity 或 Fragment 中获取用户选择的媒体 Uri 列表
     */
    public static List<Uri> obtainResult(Intent data) {
        return data.getParcelableArrayListExtra(MatisseActivity.EXTRA_RESULT_SELECTION);
    }

    public SelectionCreator choose(Set<MimeType> mimeTypes, boolean mediaTypeExclusive) {
        return new SelectionCreator(this, mimeTypes, mediaTypeExclusive);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这个类的代码还是很简单的,将外部传入的 Activity 或 Fragment,用弱引用的形式保存,防止内存泄露。然后通过 choose() 方法返回 SelectionCreator 用于之后参数的配置。等到图片选择完成后,我们可以在 Fragment 或 Activity 中的 onActivityResult() 中通过 obtainResult() 获取我们所选择媒体的 Uri 列表。

SelectionCreator
public final class SelectionCreator {
    private final Matisse mMatisse;
    private final SelectionSpec mSelectionSpec;

    SelectionCreator(Matisse matisse, @NonNull Set<MimeType> mimeTypes) {
        mMatisse = matisse;
        mSelectionSpec = SelectionSpec.getCleanInstance();
        mSelectionSpec.mimeTypeSet = mimeTypes;
    }

    public SelectionCreator theme(@StyleRes int themeId) {
        mSelectionSpec.themeId = themeId;
        return this;
    }

    public SelectionCreator maxSelectable(int maxSelectable) {
        mSelectionSpec.maxSelectable = maxSelectable;
        return this;
    }
    // 其余方法都类似上面这两个,这里面就不贴出来了

    public void forResult(int requestCode) {
        Activity activity = mMatisse.getActivity();
        Intent intent = new Intent(activity, MatisseActivity.class)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/780561
推荐阅读
相关标签
  

闽ICP备14008679号