定义阴影与裁剪视图

阿里云产品限时红包,最高 ¥1888 元,立即领取

这是来自 Google 官方的 Material Design 培训教程的翻译,受个人水平所限,难免有翻译不对的地方,欢迎交流指正。

Material design 为 UI 元素引入了海拔的概念。海拔能够帮助用户理解每个元素的相对重要程度,并关注正在运行的任务。

视图的海拔有 Z 属性来表示,决定它的阴影的视觉展示:拥有更高 Z 值的视图打造更大,更软的阴影。拥有更高 Z 值的视图会挡住低 Z 值的视图,视图的 Z 值多少并不影响视图的尺寸。

阴影由被抬起视图的父视图来绘制,并默认由父视图进行视图裁剪。

在某些动作中,当控件临时上升到其他普通视图之上时。海拔对于创建动画非常有用。

Material design 中海拔相关的更多信息,可以查看 3D 空间中的物体

为视图设置海拔

视图的 Z 值有两个组件:

  • 海拔:静态组件。
  • 变换:用于动画的动态组件。

Z = elevation + translationZ

不同视图海拔的阴影

在布局定义中设置视图的海拔,使用 android:elevation 属性。在活动的代码中设置视图的海拔,使用 View.setElevation() 方法。

设置视图的变换使用 View.setTranslationZ() 方法。

新的 ViewPropertyAnimator.z() 和 ViewPropertyAnimator.translationZ() 方法使得视图海拔的动画变得简单。更多信息可以查看开发者指南中的 ViewPropertyAnimator 和 Property Animation。

你可以使用 StateListAnimator 来以声明的方式指定这些动画。当在状态的变化中出发动画时,这将非常有用,例如当用户按下按钮时。更多信息,可以查看 动画视图状态改变

测量 Z 值的单位是 dp。

自定义视图阴影和轮廓

视图背景图片的边沿决定了它的阴影的默认形状。轮廓代表了图形对象的外围形状并定义了触摸反馈的波纹区域。

假设下面的视图,定义了背景图片:

1
2
3
4
5
<TextView
android:id="@+id/myview"
...
android:elevation="2dp"
android:background="@drawable/myrect" />

背景图片定义为具有圆角的矩形。

1
2
3
4
5
6
<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#42000000" />
<corners android:radius="5dp" />
</shape>

视图打造了具有圆角的阴影,背景图片定义了视图的轮廓。

提供自定义的轮廓来覆盖视图阴影的默认形状。

在代码中为视图定义自定义的轮廓:

  1. 继承 ViewOutlineProvider 类。
  2. 覆盖 getOutline() 方法。
  3. 通过 View.setOutlineProvider() 方法为视图设置新的轮廓提供者。

使用 Outline 类中的方法可以来创建椭圆形或者带有圆角的矩形轮廓。视图默认的轮廓提供者从视图的背景中获取轮廓。要阻止视图生成阴影,只要将它的轮廓提供者设置为 null 就可以了。

裁剪视图

裁剪视图让改变视图的形状变得简单。你可以通过裁剪视图让其与其他设计元素之间保持一致,也可以改变视图的形状来反应用户输入。通过 View.setClipToOutline() 方法或者 android:clipToOutline 属性来对视图的轮廓区域进行裁剪。只有矩形,圆形和圆角矩形轮廓支持裁剪,能否裁剪是由 Outline.canClip() 方法决定的。

要裁剪视图中图片的形状,需要将图片设置为视图的背景,并调用 View.setClipToOutline() 方法。

裁剪视图是一个代价昂贵的操作,因此不要对用于裁剪视图的形状做动画。要达到这样的效果,可以使用
Reveal Effect 动画。

原文:Defining Shadows and Clipping Views