写点什么

【译】彻底理解 Android 中的阴影,三年经验 Android 开发面经总结

用户头像
Android架构
关注
发布于: 刚刚
  • Outline

  • 自定义的 ViewOutlineProvider


在深入到阴影和光线之前,我想告诉你我们的真实环境什么?

什么是 3D?

真实的物质环境,是一个三维空间,这意味着所有的物体对象都有 X、Y 和 Z 维度。Z 轴与显示器的平面垂直对齐,正 Z 轴朝向观察者延伸。在 Material Design 的世界里,每个物体都有 1dp 的厚度。


Android 的 Depth

Material Design 不同于其他的设计指南,因为它增加了 Depth(深度)的概念。而 Depth 在真实的视觉中,有重要的意义。


我们可以认为我们桌子上有一层纸,如果我们再贴一张纸,我们的眼睛会觉得它有一个深度。


让我们通过 Material Design 的应用截图来想象它。



让我们来看看屏幕上的各个元素。


  • 屏幕(表层 - 深度为 0 )

  • CardViews

  • App UI 布局

  • 浮动动作按钮(Floating Action Button)


这里面,每个元素都在另一个元素之上。CardView 可以滚动,所以我们可以说第一层是可滚动的内容,第二层是 AppBar 布局,第三层(顶层)是浮动动作按钮。


那么,我们如何定义层级?我们如何让用户感受到深度?答案是: Z 轴。

Android 中的 Z 值是什么?

View 的 Z 值有两个组成部分:


  • Elevation:高度,一个静态值。

  • Translation Z:Z 轴变动值,用于动画的动态值。


我总是在想 Elevation 和 Translation Z 有什么区别。


Elevation 是静态的,所以你最好不要动态的去改变他。如果你想在 Z 轴上做动画的效果(如按下态或者静止态),你需要使用 Translation Z 属性。


Translation Z 是动态的,当你创建一个空白项目,并在其中增加一个按钮的时候,当你按下它你将会看到阴影变大了。实际上 Elevation 并没有变化,而是 Translation Z 属性在变化。这是 A


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ndroid 使用默认的状态列表动画,更改 Z 属性。


Z Vaue = Elevation + TranslationZ


如果我们改变两个具有 Z 值的 View,让它们相交。Android 如何处理屏幕上的层级?让我用一个我设计的图表向你展示。



另外一个问题,我们如何看到物体的影子?我们是需要一个阴影吗?不是的,我们是需要一个光源。

Android 中的光源是什么?

其实问题不在于是什么?而是在哪里。


在现实中,如果我们手持一个手电筒照桌子上的物体(从它的顶部),阴影的长度会缩短,当你降低它的时候,阴影的长度会增加。


那么在 Android 的 Material Design 中,光源在哪里?在顶部?还是有角度的?经过一番研究,我发现这个现象。



Android 中存在两个光源,顶部那个是关键的光源,而另一个是环境光源,我们看到的阴影实际上是这两个光源的组合。


让我们看看显示的效果。



在 Android 中,我们有很多小部件。按钮、CardView、对话框,抽屉等所有这些都是视图。如果有一个光源,我们就有阴影。那么我们如何在 Android 中决定 Z 值呢?Material Design 是如何规定这些的?


有一个示意图来反映这种情况。


静止或者按下

正如我之前提到的,在 Android Framework 中,一些动画是为小部件而实现的。如果你在布局中放置浮动操作按钮,默认情况下它将具有 6dp 的 Elevation。但是你会注意到当你按下按钮时,FAB 的 Elevation 将会提高到 12 dp


让我告诉你,在这个过程中发生了什么。


其实 FAB 有 6dp 的 Elevation。当您按下按钮时,translationZ 值开始增加。ViewPropertyAnimator 通过将 translationZ 值从 0dp 更改为 6dp 来 让视图动起来。如果你释放按钮,ViewPropertyAnimator 播放动画,将 translationZ 从 6dp 变到 0dp。你可以为你的视图创建自定义状态列表动画,并将其添加到你的视图上。


我们来看一下这个过程的流程图。


阴影的秘密:Outline

Outline 是一个属于 android.graphic 下的类,看看它的文档都说了什么


定义一个简单的形状,用于图形的边界区域。

可以为 View 计算,也可以由 Drawable 计算,以驱动由视图投射的阴影的形状,或剪裁视图的内容。


每个 View 都有默认的轮廓以显示其阴影。如果我们创建一个可绘制的自定义形状,其轮廓将根据其形状在内部进行计算。所以,如果我们画圆,轮廓将会是圆的。如果我们绘制矩形,轮廓将是矩形。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
【译】彻底理解 Android 中的阴影,三年经验Android开发面经总结