Fresco正传(3):DraweeHierarchy分析

前言

在正式开始分析之前,还是看一下DraweeHierarchy的继承体系,做到心中有数。

看三个类的命名好像也只有SettableDraweeHierarchy可以猜出来一些 – 可设置的层次结构。

GenericDraweeHierarchy你是不是哪里眼熟?没错,在GnericDraweeViewinflateHierarchy()的方法中,使用GenericDraweeHierarchyBuilder构建出了一个DraweeHierarchy的实例对象。

值得一提的是,DraweeHierarchy的主要职责是提供可显示的图片,也就是Draweable,而在Fresco中,默认定义了众多的Drawable类,并在GenericDraweeHierarchy的得到了充分的使用。

由于Drawable体系知识我还没有研究,就先把Fresco自定义的Drawable的体系脉络先梳理一下,以便混个眼熟。

ArrayDrawable-FadeDrawable

看一下ArrayDrawable类的注释,可以知道:

  1. 这个Drawable包含其他的显示元素数组(层),并且都是以数组顺序绘制的,因此,元素数组的最大值(最末尾元素)将被绘制在顶部。
  2. 这个Drawable类似Android的LayerDrawable类,但是LayerDrawable并不支持动态添加和移除图层。

简单明了,继续看一下FaseDrawable类的注释:

  1. 可以使指定的图层逐渐消失
  2. 支持任意数量的图像;有五种不同的方式让图层逐渐消失。
    1. fadeInLayout:淡入指定的图层直到完全显示
    2. fadeOutLayout:淡出指定的图层直到完全透明
    3. fadeOutAllLayers:淡出所有的图层直到完全透明
    4. fadeToLayer:淡入指定的图层直到完全显示,同时淡出其他图层直到完全透明。
    5. fadeUpToLayer:淡入一个图层的集合到指定的图层并让指定的图层完全显示,同时淡出其他的图层至完全透明。

ProgressBarDrawable

  1. 基于level的值,显示一个进度条。

ForwardingDrawable体系

先看一下ForwardingDrawable类的注释:

  1. 目标是代理drawable的功能到一个内部实例。

例如GenericDraweeHierarchy中的RootDrawable内部类。

正文

与前一篇文章不同,这次分析DraweeHierarchy按照从上至下的顺序来。

DraweeHierarchy

DraweeeHierarchy是一个接口,同时接口中也只有一个getTopLevelDraweable()方法,想要了解其中暗含了那些意图,只能从注释入手。

  1. 为了可以动态改变显示的图像,DraweeHierarchy被组装成一个树状。
  2. 树状的层级比Android传统的嵌套视图,更加轻便。
  3. 树状层级的细节被隐藏,外界无法看到。所有的可见的图像,都是最顶级Drawable。

当然,这样子你可能会更清晰一些。

FaseDraweable作为顶层图像,隐藏了其与的细节。

SettableDraweeHierarchy

看一下接口注释,我们能了解如下信息:

  1. SettableDraweeHierarchy接口代表可设置的层级结构。直到实际的图片被显示之前,它应该显示一张占位图;如果加载失败了,层级结构应该可以选择一张失败的图片用于显示。
  2. 这些方法只能被Controller所调用。

此外,本接口还提供了如下方法:

  1. 图像可以被重置
  2. 图像可以设置进度
  3. 设置失败
  4. 设置重试
  5. 设置controllerOverlay

为了便于理解,还是给出层级结构的两种不同的表示方式。

GenericDraweeHierarchy

作为抽象接口的实现类,无非就是在原本抽象特性的基础上,又增加了一些其他的特性。

通过类注释,来粗略的看一下本类都做了些什么。

  1. 一个可设置的层级结构在成功显示实际图片前,会一直显示占位图。
  2. 如果提供了失败的图片,失败的图片将会被用于失败的情况下。
  3. 如果提供了重试的图片,重试的图片将会被用于失败并且重试可用的情况下。
  4. 如果提供了进度条,进度条会被一直显示直至加载完毕。

这样,层次结构就好像下面这个样子,从上至下依次执行状态:

分析完了基本脉络,接下来看看具体的代码是怎么做的。想实例化GnericDraweeHierarchy类,必须要走构造方法,不过估计看到庞大的构造方法你就会眼晕。同时,想要构造方法必须要传入GenericDraweeHierarchyBuilder的一个实例。

 GenericDraweeHierarchy(GenericDraweeHierarchyBuilder builder) {
     // ... 省略N行,构造GenericDraweeHierarchy的代码。
 }

在构造方法上按ALT+F7,看看在哪里调用了它。结果发现只有在GenericDraweeHierarchyBuilderbuild()方法中被调用了。

public GenericDraweeHierarchy build() {
    validate();
    return new GenericDraweeHierarchy(this);
}

根据前一篇博客的分析,可以知道,在解析XML属性时,实例化了GenericDraweeHierarchyBuild类,并使用建造者模式,构建出了GenericDraweeHierarchy的实例对象。这样,这两端DraweeHierarchyDraweeView就被我们串联起来了。

再回到GenericDraweeHierarchy类的构造方法中,其实内部做的操作就是上图的映射,就是更加代码化了:

  1. 使用numLayers记录层级总数,每创建一个分子就+1。
  2. 创建占位图分支,如果用户未自定义,给一个透明的占位图;该分支是否需要圆角效果;该分支是否需要包裹缩放效果。此处的waybeWrapWithScaleType()的是包装设计模式的应用。
  3. 创建实例图像分支,默认给一个透明图;该分支是否需要缩放效果;是否需要Matrix效果;设置颜色过滤器;
  4. 创建进度条分支,判断该分支是否需要缩放效果;
  5. 创建重试分支,判断该分支是否需要缩放效果;
  6. 创建失败分支,判断该分支是否需要缩放效果;
  7. 创建覆盖层分支
  8. 根据层级总数,创建一个Drawable数组,并将填入对应的分支。随后使用该数组构造一个FadeDrwable类的实例(这个前文提过)。判断是否需要对FadeDrawable的实例应用圆角效果。最后,使用最后的Drawable构造一个RootDrawable的实例,并作为最顶层的图像(mTopLevelDrawable),其中RootDrawableForwardingDrawable的子类,起到了代理作用。

就简单来说,将各种场景的Drawable放入一个数组中,并包装成FadeDrawable以便在各种场景间切换,并根据其构造一个代理对象,以便添加一些需求。

一图胜千言,希望我画的图各位能看懂:O(∩_∩)O哈哈~

最后

DraweeHierarchy的体系分析就基本完成了,如果觉得对您有帮助,多多留言哦。

github:https://github.com/biezhihua

总览:http://blog.csdn.net/biezhihua/article/details/49795527

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值