文章首发 公众号:夜猫设计话
发现问题
两端的开发阴影实现有差异,阴影效果不规范。
阴影组件化
组件化的目的,全局设计阴影规范统一,避免重复造轮子。两端统一。
三端实现方式
Web
CSS box-shadow 不占位
支持修改阴影偏移量、颜色透明度、模糊半径阴影尺寸(扩展)和内外阴影。
iOS
UIView阴影设置 不占位
支持修改阴影颜色、阴影偏移量、阴影透明度、阴影模糊半径参数。
Android
1. elevation(组件属性)
优点:绘制效率高,使用自带的api不用添加多余的drawable文件,并且支持 translationZ 动画方便实现点击的动画效果;不占位
缺点:低版本不显示,方向颜色不可控,自带的属性设置参数有限;
注意:View要带透明度,否则是没有效果;
2. CardView(组件自带)
优点:CardView是自带阴影的是Materail设计的组件,效率高;不占位
缺点:阴影方向颜色不可控;
注意:CardView模拟的光源在屏幕中心正上方阴影显示角度会有所差异;
3. shape(作为背景绘制所以会占位,它的绘制原理是一层层的由深到浅的形状作为阴影)
优点:颜色方向可控制;占位
缺点:没有模糊效果阴影不自然有点生硬(较弱的阴影不太容易看出来);
注意:占位的阴影要考虑预留出阴影的空间;
4. SCardView
同CardView显示效果,可通过代码调整边角光源调整阴影方向和颜色,但需考虑版本兼容性问题;
5. 自定义View
理论上我们想要的阴影效果都可以实现,但是如果脱离了系统原生属性就需要考虑的太多;
自定义阴影针对特殊的载体样式和阴影,代码实现较为复杂,绘制成本较高,非必要情况下不建议;
切图阴影
除代码实现方式外移动端还常用切图的方式实现阴影,切图的方式要分场景,例如特效按钮或卡片;
在移动端开发中也常有用点9(Android)的方式来实现阴影,其实就是在CardView下方用png图片做背景。
在使用切图做背景阴影的时候需要注意:
为减少内存 安卓点9切图拉伸区域够用就好,不宜过多的拉伸区域;
iOS png拉伸位置不可在圆角处;
切图的好处就是能在较低版本上显示,因为elevation属性在Android5.0之前是没有效果的,当然5.0以前的设备基本上已经淘汰,如果应用不考虑这些较低版本还是比较建议使用代码实现。
iOS和Android设计规范中阴影有所差异,我们知道Material Design中的材料宽度是自由可变的,阴影是由相对高度Z轴来决定的,因此我比较建议我们通过Material Design中自带的属性来elevation解决阴影问题,CardView是自带阴影的是Materail设计的组件,可通过设置elevation属性值来修改阴影效果,而且在Material Design中elevation属性决定了控件的权值,控件会根据权值来决定其显示的层级。
其实用心去细调安卓通过自定义阴影最终总能达到和iOS视觉呈现效果一致的阴影,但是我们需要解决的问题是:是否占位和视觉一致。
什么是阴影占位?
在我们设计的过程中基本不会考虑占位问题,因为设计稿阴影是不占位的。
举个例子
当开发中阴影占位的时候,我们预留的间距是需要大于等于阴影距离的。
所以我们看到当阴影占位的时候很多情况下是无法满足我们的设计需要的,因为在大多数情况下卡片如果在一起的话阴影是超出间距的。
因此我们需要阴影不占位。
当阴影不占位时设计时则不需考虑阴影是否预留空间,并且也更符合物理现状,影子是一个虚的东西,不需要空间。
CSS和iOS的阴影是不占位的,Android中只有使用Elevation不占位;并且绘制效率高,也就是使用了Material Design的常规阴影,常规阴影透明度不可控,并且是通过深度Z来控制阴影那如何才能和iOS一致呢?下面先简单介绍下如何制定阴影的规范再根据实例来解决安卓阴影如何和iOS一致的问题。
如何制定常规阴影规范
什么是阴影?
影,又称影子、阴影(英语:shadow)是一种物理现象,是光线被不透明物体阻挡而产生的黑暗范围,与光源的方向相反。在光源固定的情况下,影子反应了物体离我们的距离。在屏幕中则是直接通过模拟控件的影子来告知用户其距离及层级。
光源
阴影的方向决定了光源的位置,在屏幕中虽然我们可以自定义光源的位置,但用户都已习惯了在屏幕上方。
高度
人们视觉所关注的信息总是由大到小,由深至浅;
在移动端设计中,我们把阴影设置为低,中,高3个层级:
在同一个平面中选择其阴影层级,设计师根据控件所占屏幕比例来决定阴影级别。
强度
根据卡片是否为纯白色底来决定阴影强度,也就是阴影透明度,非纯白色情况下透明度为常规的2倍呈现。
阴影参数
具体的参数根据应用风格调性及实际情况来定,仅做参考。
如何解决Android阴影效果
在Android里的阴影总是这样的
我们发现通过Z轴和Y轴的控制其实能很接近我们想要的效果,仅仅只需要调低透明度即可,然而Elevation并不支持自定义透明度。
前面提到过点9图的阴影原理其实就是下边贴张图片做阴影,因此是否通过该原理分为两层,底层做阴影调整透明度,顶层做卡片能否达到这样的效果?
我们来测试一下:
我们发现通过调整Z轴阴影值及底层透明度阴影效果是可以和设计稿视觉效果保持一致的,其实安卓的阴影也可以很通透很清秀,也可以不占位。根据我们的设计稿效果调整好相同视觉效果的参数进行封装成组件即可。
其实在很多产品中也会使用分层阴影的方式;
例如Facebook的这个通知类型图标阴影,当网络情况特别差的时候这个区域的阴影是预先加载出来的,说明阴影和上层是分开的。
THX