知乎 Matisse 源码解析,探究高效图片选择库的秘密

Matisse是知乎开源的高效图片和视频选择库,具备简洁代码、高度可定制性等特点。本文深入解析其整体设计、资源加载、图片墙实现及预览界面等关键部分,探讨其使用Loader机制、建造者模式以及如何优化用户体验。
摘要由CSDN通过智能技术生成

目录

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

一、基本介绍


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

上面的使用代码,我们以 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);
    }

}

这个类的代码还是很简单的,将外部传入的 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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值