如何使用 Jetpack Compose 创建 Android 13 波浪滑块?

问题描述 投票:0回答:1

Android 13 在快速设置中为其媒体控件引入了波浪形进度条。

如何在 Jetpack Compose 和 Compose Multiplatform 中重新创建它?

这是 Flutter 和 Dart 的相关问题:Squiggly Seekbar with Animation in Flutter

android kotlin canvas android-jetpack-compose compose-multiplatform
1个回答
0
投票

TLDR:有一个库:Wavy slider
披露:我是该库的作者。

有两种方法可以绘制这种波浪图案。

  1. 使用Bézier曲线(在版本0.5.0及更早版本的库中实现
    (依次指定具有一或两个控制点的两个节点/顶点)
  2. 使用三角函数 sinecosine 函数
    (水平逐像素前进并绘制
    (x, sine(x))
    点)

Android 13和14已使用贝塞尔曲线(这里是Android 14波浪形进度的源代码)。

使用贝塞尔曲线

贝塞尔曲线有两种变体(据我所知):

  1. 二次贝塞尔曲线(两个节点和一个控制点)
    (称为 二次,因为它的方程包含一个 2 次多项式)
  2. 三次贝塞尔曲线(两个节点和两个控制点)
    (称为 cubic 因为它的方程包含一个 3 次多项式)

因此,绘制波浪的一种简单方法是使用三次贝塞尔曲线。 x 从

0
开始。然后使用三个参数调用
cubicRelativeTo
:控制点 1、控制点 2 和下一个点。将第一个控件放置在 (middle, waveHeight) 中,将另一个控件放置在 (middle, -waveHeight) 中,将下一个点放置在
waveLength
中。将 x 设置为 waveLength 并对整个波的整个长度重复此操作 (x < totalWaveLength).

缺点是,实际波高小于提供的值。 要获得准确的高度,这篇文章可能会有所帮助。

请参阅有关贝塞尔曲线的综合指南:https://pomax.github.io/bezierinfo/

使用三角正弦或余弦函数

使用两个函数中的哪一个并不重要(它只影响波的初始相位,即位置)。我们将使用正弦函数。

因此,将

x
0
进展到
sliderTotalWidth
像素(在一个简单的 for 循环中),并给出以下内容:

  • H:波浪总高度(以像素为单位)
  • L:以像素为单位的波长(波形重复的长度)
  • S:滑块总高度(以像素为单位)

radians = (x + waveShiftPx) / L * (2 * 3.14)

y = (sin(radians) * H + S) / 2

然后可以为每对x和y调用画布

lineTo(x, y)

然后,您只需要以所需的速度(持续时间)无限地设置

0
L
之间的波移动画,并提供该动画值作为
waveShiftPx

要查看完整的实现,请参阅绘制波浪的库的核心文件

© www.soinside.com 2019 - 2024. All rights reserved.