正文共: 2031字 32图
预计阅读时间: 6分钟
当你的设计师要求你在某个 View 上增加阴影效果,那你只需要认真阅读本文,阴影的问题就不再是问题。
全文太长了,我拆分成三篇来发布,今天是第三篇,终于要完结了。
一、前言
之前两篇文章,已经介绍了一些常规的方式,在拟物化的设计里,使用标准 Api 、9patch、FloatingActionButton 的原理,设定 Material Design 里的阴影效果。
有兴趣可以先看看之前的文章两篇文章:
先来看看实现的效果,虽然多,但是它们实现的方法都不相同。
二、模拟 CardView 实现的阴影
我们知道,在 Android 对 Material Design 的效果中,有一些控件,就是自带阴影效果的,并且它也是对低版本兼容的。例如:FloatingActionButton 、CardView 等。
那么,本小结就来看看 CardView 实现阴影的原理。
2.1 CardView 的阴影原理
CardView 在 support.design 包中,你是找不到的,它被放在了 cardview-v7 包中,现在已经可以单独引用了。
CardView-v7 包中,代码非常的少。
一共就这么几个,一样就可以看到来,有一些类是做 Api 版本兼容的,并且也上如此。
在其中,还有一个 RoundRectDrawableWithShadow 类,它就是我们要找到,CardView 实现的 Drawable,它只在 CardViewJellybeanMr1 和 cardViewGingerbread 这两个类中使用,CardViewApi21 中,依然是使用的 setElevation()
方法来处理的阴影。
用之前 FAB 的经验,将 RoundRectDrawableWithShadow 直接拷贝出来,然后运行你会发现有报错。主要是因为其中有个静态的变量 sRoundRectHelper 为空了,没有被初始化。
仔细查源码你会发现,它在 CardViewJellybeanMr1 和 CardViewGingerbread 的实现原理并不相同。它们会在 initStatic()
方法中,对 sRoundRectHelper 变量进行初始化。
CardViewJellybeanMr1.initStatic() 方法如下:
CardViewGingerbread.initStatic() 方法如下:
可以看到它们的实现方法,差异还是挺大的。
了解清楚这些,我们只需要 RoundRectDrawableWithShadow 的构造方法中,根据 Api Level 对他们进行不同的初始化即可,这些代码也上拷贝出来就可以直接用的。
绘制阴影的部分都大同小异,这里就不详细看了,有兴趣的可以执行查看源码,主要关注 drawShadow() 方法即可。
2.2 举个 CardView 阴影的例子
首先,将 ShadowDrawableWrapper 完整的拷贝到我们的工程里,并且在构造方法中,根据 Api Level ,用不同的逻辑初始化 sRoundRectHelper 。
还需要将 ShadowDrawableWrapper 使用到的几个默认参数值也拷贝出来,当然我们已经有源码了,直接写死也可以,我这里选择将它们原样拷贝出来。
然后我们就可以在代码中,使用这个 RoundRectDrawableWithShadow 了。
最终,看看实现的阴影效果:
2.3 CardView 模拟阴影小结
CardView 模拟的阴影效果,在低版本上,也上会占用 View 的原本的大小来绘制阴影,所以视觉上也会偏小。不过在高版本上,依然上使用 elevation来实现的,也就会造成在不同 Api Level 下,显示的效果不一致的问题。
三、使用开源库 ShadowLayout
最后再介绍一个开源库,用一个 LayoutView 来实现阴影的效果。
Github 地址:
https://github.com/dmytrodanylyk/shadow-layout
它完整的库也只有一个类加一些属性,整个项目结构如下。
并且提供了几个属性,用于配置阴影的效果。
使用起来也非常的方便,它上直接继承自 FrameLayout 的,所以需要作为一个布局来使用。
最后看看实现的效果。
它基本上可以实现一个类阴影的效果,不过应该是算法的问题,导致阴影的边缘太齐了,看着不真实,一般不推荐使用。
四、结语
介绍了这么多在 Android 下实现阴影的效果,接下来给一张完整的效果图吧,如果本文都看完了,我想你应该知道自己应该选择那种方案了。
今天在承香墨影公众号的后台,回复『成长』。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、Web项目源码。
推荐阅读:
目前5000+人已关注加入我们
点赞或者分享吧~
点击『阅读原文』查看更多精彩内容