RippleDrawable 跨版本视觉演进
从 Android 5.0 引入 Material Ripple,到 12 用 RuntimeShader 重写为 sparkly 涟漪——本页面用 WebGL Fragment Shader 1:1 移植 AOSP frameworks/base/graphics/.../RippleDrawable.java 下的实现。
14 versions2 Legacy7 Refactored5 SparklyAPI 21 → 35
BoundedON
7-8 物理路径:ON=350px,OFF=对角线
Duration1.0×
0=暂停,1=原速,10=10倍时长(慢动作)
Width280px
按钮宽度 120-500px
Height80px
按钮高度 40-240px
统一背景色
#1e293b所有卡片共用此按钮底色
自定义 Ripple 颜色
#ffffff关闭时按按钮亮度自适应深/浅色
Sparkly · Material You — Android 12+ · RippleShader (RuntimeShader) · sparkles + turbulence
Android 12
SAPI 31 · 2021
12
tap
- ·★★ 重大重写:RippleShader extends RuntimeShader
- ·ENTER_ANIM_DURATION = 450ms,EXIT_ANIM_DURATION = 375ms
- ·NOISE_ANIMATION_DURATION = 7000ms(连续 sparkle 相位)
- ·Sparkles + Turbulence + softCircle + softRing 多层合成
- ·in_maxRadius = radius × 2.3
- +3 more
color
RippleShader.java ↗Android 12.1
S_V2API 32 · 2022
12.1
tap
- ·同 12.0 的 RippleShader 体系
- ·turbulence 旋转相位略调(PI_ROTATE_LEFT/RIGHT 微调)
- ·稳定性修复,视觉与 12.0 一致
color
RippleShader.java ↗Android 13
TiramisuAPI 33 · 2022
Android 14
UpsideDownCakeAPI 34 · 2023
14
tap
- ·同 12/13 RippleShader
- ·Predictive Back 手势引入:返回手势中 ripple 不再额外触发
- ·edge-to-edge 默认开启,触摸坐标系跟随 WindowInsets
- ·视觉与 13 一致
color
RippleShader.java ↗Android 15
VanillaIceCreamAPI 35 · 2024
15
tap
- ·同 12-14 RippleShader
- ·★ 新增 STYLE_PATTERNED(@hide):可选带噪声花纹的样式
- ·默认仍为 STYLE_SOLID(与 12.0 视觉一致)
- ·edge-to-edge 强制:ripple 区域受 status/nav bar inset 影响
color
RippleShader.java ↗如何使用
- 同时只展示一个: 鼠标 hover 或键盘 focus 任一卡片,该卡片的 WebGL canvas 立即挂载并预览; 移到其他卡片时旧的自动卸载、新的挂载,全局始终只有一个 WebGL context。
- 连续点击: 与 AOSP 一致——每次 pointerdown 新建一个 RippleForeground 对象, 松手时移到 exiting 列表;快速连点会出现多个 ripple 叠加(最多 10 个)。
- Bounded 开关: 仅对 Refactored 7-8 生效。ON=350px 固定半径 + 按下不显示;OFF=对角线 + 立即显示。
- Duration 滑块: 动画时长倍率。0=暂停(虚拟时间冻结),1=原速,10=10倍时长(慢动作便于观察)。
- Width / Height: 调整 demo 按钮的宽高,观察不同尺寸下 ripple 的表现。
- 深色模式: 右上角 ☀️/🌙 按钮切换页面浅色/深色主题,跟随系统偏好初始化。
- 统一背景色: 开启后所有卡片共用同一按钮底色(可用取色器自定义), ripple 颜色会自动按按钮亮度切换深/浅(亮色按钮→深色 ripple,反之亦然)。
- 自定义 Ripple 颜色: 开启后用取色器指定 ripple 颜色(保留各版本原 alpha),优先级高于自适应。
源码映射
| Version | Style | Source File |
|---|---|---|
| Android 5.0 | legacy | Ripple.java ↗ |
| Android 6.0 | legacy | Ripple.java ↗ |
| Android 7.0 | refactored | RippleForeground.java ↗ |
| Android 7.1 | refactored | RippleForeground.java ↗ |
| Android 8.0 | refactored | RippleForeground.java ↗ |
| Android 8.1 | refactored | RippleForeground.java ↗ |
| Android 9.0 | Refactored 9+ | RippleForeground.java ↗ |
| Android 10 | Refactored 9+ | RippleDrawable.java ↗ |
| Android 11 | Refactored 9+ | RippleAnimationSession.java ↗ |
| Android 12 | sparkly | RippleShader.java ↗ |
| Android 12.1 | sparkly | RippleShader.java ↗ |
| Android 13 | sparkly | RippleShader.java ↗ |
| Android 14 | sparkly | RippleShader.java ↗ |
| Android 15 | sparkly | RippleShader.java ↗ |