本文译自Draw sleep timeline graph in Compose,原文由Viktor Mykhailiv发布于2025年1月31日。
译者按: 我们在前面的降Compose十八掌系列中讲解过在Compose自定义绘制的方法,可以先温习一下上一篇文章。这篇文章是提升自定义绘制技巧的一个非常好的实战例子。
当内置组件不能完全满足我们的应用需求时,自定义绘图非常有用。本文提供了创建自定义睡眠时间线图表的指南,类似于你在Fitbit 应用中找到的图表。
在 Compose 中如何绘图?
要开始在 Compose 中绘图,我们可以使用绘图Modifier或 Canvas可组合函数,这为我们提供了 DrawScope — 一种声明式、无状态的API,用于绘制形状和路径,而无需消费者维护底层状态。DrawScope实现还提供了尺寸信息,并且变幻是相对于本地平移完成的。
注意: Jetpack Compose(仅限 Android)和 Compose Multiplatform(桌面、Android、iOS、Web)具有类似的绘图 API。下面的屏幕截图是在桌面(macOS)上制作的,但所有平台上的结果都是相同的(查看最后一张屏幕截图)。
1 2 3 4 5 6 7 8 9 |
|
啥是睡眠时间表?
我们可以在 Health Connect 中读取或写入睡眠数据。睡眠数据显示为会话,可分为以下睡眠阶段:
- 清醒:用户在睡眠周期内清醒。
- 浅睡眠:用户处于浅睡眠周期。
- 深睡眠:用户处于深睡眠周期。
- REM:用户处于 REM 睡眠周期。
这些值表示用户在一定时间范围内经历的睡眠类型。SleepSessionRecord 数据类型包含两部分:
- 整个睡眠过程,涵盖整个睡眠时间。
- 睡眠过程中的各个阶段,例如浅睡眠或深睡眠。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
需要一点数学计算
在睡眠期间,我们可以在不同时刻多次处于同一阶段。我们需要计算相对于睡眠的起点和终点。
要在 Compose 中绘制矩形,我们需要 topOffset 和 size。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
绘制
让我们构建自定义 Canvas 来绘制睡眠过程的一个阶段,例如深度睡眠。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
如果我们使用之前定义的睡眠会话运行项目,我们将看到 3 个矩形:1 个灰色矩形表示背景,2 个紫色矩形表示深度睡眠阶段。
1 2 3 4 5 6 7 |
|
为了绘制睡眠过程的所有阶段(清醒、快速眼动、浅睡眠和深睡眠),我们需要进行一些调整,将每个阶段类型垂直绘制为列组件,办法是逐行绘制并对下一行应用一些偏移量(offset)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
添加文本
要在 Compose 中绘制文本,我们通常可以使用 Text 可组合项。但是,在我们的示例中,我们处于 DrawScope 中,我们可以使用 DrawScope.drawText()方法。
绘制文本与其他绘制命令略有不同。通常,我们为绘制命令提供绘制形状/图像的大小(宽度和高度)。对于文本,有几个参数可以控制渲染文本的大小,例如字体大小、字体、连字符和字母间距。我们需要使用 TextMeasurer 来获取文本的测量大小,具体取决于上述因素。
请到我的Github repo中查找完整示例代码:https://github.com/vitoksmile/Sleep-timeline-graph。