Elevation — 基础、阴影和 Android 中的 Z 坐标

作者: IT Sectr 发布日期: 2026-02-28 阅读时间: 9 分钟

Elevation — Material Design 的基本概念,定义元素沿 Z 轴(垂直于屏幕)的高度。Elevation 以 dp 为单位测量,直接影响元素投射阴影的大小和模糊程度。Elevation 越高,元素离用户越近,其视觉权重越明显。根据 Material Design 3(Google,2026),卡片的标准 elevation 为 1 dp,FloatingActionButton 为 6 dp,对话框为 24 dp。有关阴影实现的更多信息,请阅读关于 UI 阴影的文章

要点

  • Elevation — 元素相对于屏幕表面的高度,以 dp 为单位测量(Android)。
  • 在 Android 中,elevation 通过同名的 View 属性或通过 translationZ 进行动画管理。
  • OutlineProvider 定义元素的形状,elevation 的阴影据此绘制。
  • Material Design 3 使用 5 个基本级别 elevation:0、1、3、6、8、12 和 24 dp。
  • iOS 上没有 elevation 的直接类似物 — 高度通过 CALayer.shadow 参数模拟。

什么是 elevation?

Elevation — 是 Material Design(Google I/O 2014)引入的度量标准,描述元素沿 Z 轴的位置。与 X 和 Y(屏幕的二维平面)不同,Z 是平面上方的高度。Elevation 以 dp(密度无关像素)表示,并决定两种视觉效果:随着 elevation 增加而变大和模糊的阴影(shadow),以及绘制顺序(具有较高 elevation 的元素绘制在具有较低 elevation 的元素之上)。

物理隐喻:想象桌子上的纸张。堆栈越高,顶层纸张的阴影越长。Material Design 中的 Elevation 的工作原理完全相同:每个元素都是特定高度的「数字纸张」。当用户与元素交互时(按下按钮、抬起卡片),elevation 会暂时增加 — 这称为「交互高度」(interaction elevation)。

根据 Material Design 指南(Google,2026),正确使用 elevation 可将界面的可扫描性提高 35%:用户更快找到交互元素,因为它们「突出」于平面内容之上。然而,过多的 elevation 级别(超过 4 个)会降低这种效果:如果所有元素都悬浮,没有一个看起来重要。

Android 中的 Elevation:属性和 API

在 Android 中,elevation 从 API 21(Android 5.0 Lollipop)开始作为 View 的内置属性实现。View.elevation 设置以像素(px)为单位的基本高度,View.translationZ 是用于动画(例如按下时)的额外偏移。总视觉高度 = elevation + translationZ。两个属性都支持通过 ViewPropertyAnimator 或 ObjectAnimator 进行动画。

xml
<!-- XML:elevation 和 translationZ -->
<Button
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:elevation="4dp"
    android:translationZ="2dp"
    android:stateListAnimator="@anim/button_elevation"
    android:text="带 elevation 的按钮" />

StateListAnimator — 一个 XML 资源,用于根据 View 状态(pressed、focused、enabled)对 elevation 和 translationZ 进行动画。例如,当按下按钮时,elevation 可以从 2 dp 增加到 8 dp,产生抬升效果。StateListAnimator 支持通过 ObjectAnimator 对任何 View 属性进行动画。

kotlin
// Kotlin:以编程方式配置 elevation
import android.animation.ObjectAnimator
import android.view.View

val myButton: View = findViewById(R.id.myButton)
myButton.elevation = 4f  // 基本高度(px)

// 按下时的 elevation 动画
val animator = ObjectAnimator.ofFloat(
    myButton,
    "translationZ",
    0f,
    8f
).apply {
    duration = 150
    repeatMode = ValueAnimator.REVERSE
    repeatCount = 1
}

OutlineProvider — 正确绘制 elevation 阴影的关键组件。默认情况下,Android 使用 ViewOutlineProvider.BACKGROUND,它基于背景 drawable 创建轮廓。对于通过 shape drawable 具有圆角的 View,需要设置自定义 OutlineProvider,否则阴影将是矩形的。Material 组件(CardView、MaterialButton)自动管理 OutlineProvider。

Material Design 3 中的 Elevation 级别

Material Design 3(Material You)改进了 elevation 系统。与 Material Design 2 的 12 个固定级别不同,M3 提供 5 个基本色调(tones),每个色调对应特定的 elevation 级别。此外,M3 在 Android 12+ 上引入了「彩色阴影」(color shadow)概念:阴影可以着色为主题强调色,而不是黑灰色。

级别Elevation应用阴影(浅色主题)
Level 00 dp背景、Surface 容器无阴影
Level 11 dp卡片、ListItem、菜单0.05 opacity,2px blur
Level 23 dp搜索栏、底部导航0.08 opacity,4px blur
Level 36 dpFAB、FloatingActionButton0.11 opacity,8px blur
Level 48 dpSnackbar、Bottom sheet0.12 opacity,12px blur
Level 512 dp导航抽屉、对话框0.14 opacity,16px blur
Level 624 dp模态对话框、弹出菜单0.15 opacity,24px blur

Interaction elevation — 用户与元素交互时 elevation 的临时增加。在 Material Design 3 中,交互元素(按钮、卡片)在按下(pressed state)或聚焦(focused state)时获得 +1–2 dp 的基础 elevation。对于 FloatingActionButton,interaction elevation 为 +6 dp。状态之间的过渡动画应持续 150–200 ms,以获得自然的触觉反馈。

Jetpack Compose 中的 Elevation

Jetpack Compose 通过 Card 和 Surface 组件支持 elevation,这些组件具有内置的 elevation 参数。与 View System 不同,Compose 通过自己的渲染引擎绘制阴影,确保在所有 Android 版本(API 21+)上行为一致。Modifier.shadow() — 一个低级修饰符,用于向任何 composable 添加阴影。

kotlin
// Jetpack Compose:通过 Surface 和 Card 实现 elevation
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Surface

Card(
    elevation = CardDefaults.cardElevation(
        defaultElevation = 4.dp,
        pressedElevation = 8.dp,
        focusedElevation = 6.dp
    ),
    colors = CardDefaults.cardColors(
        containerColor = MaterialTheme.colorScheme.surface
    )
) {
    Text("由 elevation 管理的卡片")
}

// Modifier.shadow 用于自定义形状
Surface(
    modifier = Modifier
        .shadow(elevation = 6.dp, shape = RoundedCornerShape(16.dp))
        .clickable { /* 操作 */ },
    shape = RoundedCornerShape(16.dp),
    color = MaterialTheme.colorScheme.surface
) { Text("带阴影的表面") }

Elevation 动画 在 Compose 中通过 animateFloatAsState 或 Animatable 实现。当 elevation 更改时,Compose 会自动对阴影进行动画。对于交互元素,使用 M3 InteractionSource 与 animateElevation 结合,使 elevation 响应按下、焦点和拖动。Compose 1.2+ 中的 Material 3 支持 color shadow — 着色为主题 primary Container 颜色的阴影。

iOS 中的 Elevation:高度模拟

在 iOS 上没有来自 Material Design 的内置 elevation 类似物。Apple 的 Human Interface Guidelines 不使用 Z 坐标管理阴影 — 相反,开发人员通过 CALayer.shadow* 手动配置阴影。然而,通过阴影和深度的视觉层次概念在 iOS 上同样存在:模态呈现、UIAlertController、UIPopoverPresentationController — 都使用阴影来与背景分离。

要在 iOS 上模拟 elevation,开发人员使用 shadowOpacity + shadowRadius + shadowOffset 的组合。所需「高度」越高,阴影的模糊半径和偏移越大。在 SwiftUI 中,阴影通过 .shadow() 修饰符设置参数。要在 iOS 上获得类似 Material 的行为,有 Google 的 Material Components for iOS (MDC) 库。

swift
// iOS:通过 CALayer 模拟 elevation
import UIKit

extension UIView {
    func applyElevation(level: Int) {
        let elevationMap: [Int: (CGFloat, CGFloat, CGFloat)] = [
            1: (0.05, 1, 2),
            2: (0.08, 2, 4),
            3: (0.11, 4, 8),
            4: (0.12, 6, 12),
            5: (0.14, 8, 16),
            6: (0.15, 12, 24)
        ]
        let (opacity, offset, radius) = elevationMap[level] ?? (0.08, 2, 4)
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = Float(opacity)
        layer.shadowOffset = CGSize(width: 0, height: offset)
        layer.shadowRadius = radius
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale
    }
}

// 使用
cardView.applyElevation(level: 3)  // 相当于 6 dp

Material Components for iOS (MDC-iOS) — Google 的库,将 Material Design elevation 移植到 iOS。MDC-iOS 提供具有预定义值的 MDCShadowElevation 类、用于绘制阴影的 MDCShadowLayer 和用于具有正确 elevation 的 Material 卡片的 MDCCard。MDC-iOS 通过 stateful shadow properties 支持按下时的 elevation 动画。

常见问题

Android 中 elevation 和 translationZ 有什么区别?

Elevation — 元素在 Z 平面中的基本高度(在 XML 或代码中设置)。translationZ — 用于动画的动态偏移(例如按下时)。视觉高度 = elevation + translationZ。elevation 通过 ViewPropertyAnimator 动画,translationZ 通过 ObjectAnimator 动画。对于临时高度变化使用 translationZ,对于永久变化使用 elevation。

为什么 Material Design 3 改变了 elevation 系统?

Material Design 3 将 elevation 系统从 12 个级别简化为 7 个级别,以减少设计师和开发人员的认知负担。M3 不再使用精确值(2 dp、4 dp、8 dp),而是使用具有预定义阴影参数的色调(Level 0–6)。Android 12+ 添加了对彩色阴影(color shadow)的支持,这些阴影会适应应用程序的主题。

Elevation 如何影响 Android 性能?

Elevation 本身不会影响性能,因为阴影是硬件(GPU)绘制的。但是,频繁更改 elevation(动画的每一帧)可能会导致 View 及相邻区域的重绘。对于动画,请使用 translationZ 而不是更改 elevation,因为 translationZ 针对频繁更改进行了优化。对于具有 20+ 个 elevation 元素的复杂屏幕,请启用 view.setLayerType(View.LAYER_TYPE_HARDWARE, null)

如何仅对阴影应用 elevation,而不抬升元素?

在 Android 中,elevation 始终将元素抬升到背景之上并更改绘制顺序(z-order)。如果只需要阴影而不更改 z-order,请在 CardView 中使用 cardUseCompatPadding,或通过在 onDraw() 中使用 Paint.setShadowLayer() 进行自定义阴影绘制。在 Jetpack Compose 中使用 Modifier.graphicsLayer { shadowElevation = 4f }

标准 Android 组件的 elevation 是多少?

Material Design 组件具有固定的 elevation:FloatingActionButton — 6 dp(按下时 12 dp),CardView — 1–8 dp(可配置),BottomNavigationView — 8 dp,Toolbar — 4 dp,Snackbar — 6 dp,Dialog — 24 dp。Material Components Library 中的 MaterialButton 的 elevation 为 2 dp,按下时升至 8 dp。

总结

  • Elevation — Material Design 中元素的 Z 高度,以 dp 为单位测量,决定阴影和绘制顺序。
  • 在 Android 中,elevation 通过从 API 21 开始的 View 属性设置,translationZ 用于动画。
  • OutlineProvider — 对于圆角元素的正确阴影是必需的。
  • Material Design 3 使用 7 个 elevation 级别:Level 0(0 dp)— Level 6(24 dp)。
  • Jetpack Compose 通过 CardDefaults.cardElevation() 和 Modifier.shadow() 管理 elevation。
  • 在 iOS 上,elevation 通过具有预定义 opacity/offset/radius 参数的 CALayer.shadow 模拟。
  • Interaction elevation(+1–6 dp)在按下交互元素时产生触觉反馈。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读