myMusic · 设计提案 · 2026-10-31

桌面小组件

六款桌面小组件,沿用 App 现在的三样东西:跟着封面变的配色、播放页的封面形状、连在一起的切歌按钮组。正在播放是唯一的主角,其余几款做得克制,只负责把人带到对应的功能。下面的原型都能点,顶部预览栏可以切歌、暂停、换配色。

6 款组件 Jetpack Glance 1.2 Android 6.0 起 手机 · 平板 电视没有桌面小组件

配色和深浅都跟 App

配色来源、配色风格、主题都读 App 的外观设置。默认跟随封面,切歌时所有小组件一起换色;桌面上没有过渡动画,颜色直接换。

形状跟着播放页

播放中的封面用播放页当前的形状,暂停时换成圆角方形看全图。形状在 App 里裁好,再把位图交给桌面。

按钮组照搬播放页

上一首、播放、下一首连成一组,中间一段最宽、用主色。尺寸小时只留播放和下一首。

不靠常驻刷新

切歌、暂停、收藏这些事件触发更新。时间文字交给系统计时控件自己走,进度条只在亮屏播放时 10 秒刷一次。

预览
App 主题
手机
桌面

放到桌面上的样子

两屏桌面,按 4 列、每格 84×100dp 画。第一屏是常用组合,第二屏放榜单和歌单。组件上的播放、切歌、收藏按钮可以直接点。

壁纸
背景
透明只对歌词组件生效,其余组件按半透明画。
定时关闭
桌面

组件的深浅跟 App 的主题设置走:App 是跟随系统时随手机切换,是浅色或深色时固定。可以在预览栏把 App 主题设成深色、手机保持浅色模式看看。

配色来源和 App 外观页是同一个设置(跟随封面、系统壁纸、品牌松绿、自选颜色),组件用和 App 相同的种子色和配色风格。

清单

选择器里的六款

长按桌面打开小组件选择器后看到的列表。每张卡片写默认尺寸和一句说明,说明就是 android:description 的文案。

Android 15 起选择器可以显示 App 实时生成的预览,所以这里的预览就是组件本身,带着当前歌曲的配色。

myMusic6 个小组件
主角

正在播放

七档布局,从 1×1 的封面按钮到 4×3 的歌词舞台。桌面给多大,就选能放下的最大一档,所以拖动尺寸时布局按档切换,不会等比缩放。

  1. 1
    封面和文字打开播放页
  2. 2
    播放 / 暂停后台执行,不打开 App。1×1 整块都是这个按钮
  3. 3
    上一首 / 下一首后台执行
  4. 4
    收藏写入“我喜欢”,歌单组件同步刷新
  5. 5
    歌词打开播放页的歌词视图
组件
文字

歌词

当前一句放大,下一句变淡;有翻译时翻译跟在当前句下面。只按行换,不做逐字高亮:桌面组件不能播放动画,逐字刷新也太费电。

底色用主色容器,和正在播放区分开。透明背景时文字固定白色加阴影,浅色壁纸上会不好认,所以默认实色。

没有歌词时显示“纯音乐,请欣赏”或“暂时没有歌词”,点一下照样进播放页。

一键开播

听歌模式

绑定一个平台的一个模式,比如网易云私人漫游的默认模式。点播放在后台开始漫游,不打开 App;漫游中显示当前歌曲和下一首按钮。

需要登录的模式在未登录时换成“去登录”。添加时默认选第一个已登录平台的第一个模式,之后长按组件可以重新选。

列表

榜单和歌单

点某一行,从这一首开始播放整张榜单或歌单,不弹出播放页;点标题打开对应页面。列表可以在组件里上下滑。

榜单第一名用榜单页同款拱形封面,排名变化用箭头和“新”标。歌单默认是“我喜欢的歌曲”,正在播放的那一行标成主色。

入口

快捷入口

2×2 是四瓣饼干形底板,中间是听歌识曲,四角是搜索、我喜欢、听歌模式、定时关闭。4×1 变成搜索条,点开可以直接粘贴分享链接。1×1 只留识曲。

识曲要用麦克风,只能在前台录音,所以点了会打开 App、弹出识曲面板并立刻开始听。定时关闭打开播放页的定时面板。

边界

空状态和异常

没在播放、从没播放过、封面还没下载完、定时关闭中、未登录、离线。每种都给一个能点的下一步,不出现空白卡片。

规格

配色、形状、字体

颜色角色和 App 相同,深浅跟 App 的主题设置走。主题是跟随系统时,MaterialKolor 按当前种子色生成浅色、深色两套一起交给桌面,由系统按深浅模式选;主题是浅色或深色时只交对应的一套。开了纯黑背景时,深色那套用纯黑方案。

表里的色值随预览栏的歌曲和配色变化。

原型用 OKLCH 近似 Material 色调,App 里是 MaterialKolor SPEC_2025,实际色值会略有不同。

用在哪颜色角色浅色深色
小组件 · 系统字体但愿人长久 2:08RemoteViews 只能用系统字体。数字用 Roboto 自带的等宽数字,计时不跳。
App · Roboto Flex但愿人长久 2:08Roboto Flex 只打包了拉丁字母,中文在 App 里本来就回退到系统字体,所以两边只有英文和数字不同。

圆角

外圆角用系统的 system_app_widget_background_radius,内部元素用 system_app_widget_inner_radius(Android 12 起)。更早的系统用 24dp / 12dp 的背景图。

留白

4×2 及以上内边距 16dp,2×2 以下 12–14dp。所有按钮的点击区不小于 48dp,图标 20–24dp。

半透明

背景色叠 72% 不透明度。桌面组件不能做背景模糊,所以不提供毛玻璃。

工程

怎么实现

Jetpack Glance 1.2,每款一个 GlanceAppWidget。下面是断点、刷新、点击三张表,以及开工前要先补的四项底层能力。

正在播放的断点

用 SizeMode.Exact,在 Composable 里按 LocalSize 选档。SizeMode.Responsive 每次更新要为每个尺寸各生成一份 RemoteViews,7 档就要带 7 份封面位图;播放组件刷新频繁,这笔开销不值得。

档位最小尺寸常见格数内容

什么时候刷新

全部由事件推送,updatePeriodMillis 设为 0。PlaybackService 监听播放器事件,合并 300ms 内的连续变化后再调用 updateAll。

事件更新哪些组件做法
切歌正在播放、歌词、歌单(高亮行)新封面按组件尺寸取图、裁形状,新种子色生成配色后一起推送
播放 / 暂停正在播放、歌词、听歌模式换播放图标,封面在形状和圆角方形之间切换,进度条在波浪和直线之间切换
播放进度正在播放 2×3、4×2、4×3时间文字用 Chronometer,系统自己走字。进度条只在亮屏且播放中时每 10 秒推一次,灭屏立即停
歌词换行歌词、正在播放 4×3和“系统媒体条歌词”共用当前行的计算;只在亮屏时推,两次之间至少隔 1.5 秒
收藏变化正在播放(心形)、歌单(我喜欢)写入 saved_songs 的地方统一触发
外观设置全部外观页改主题、纯黑背景、配色来源、配色风格、对比度时触发。配色来源是系统壁纸时,换壁纸也要推(App 进程在时监听壁纸颜色变化)
系统切换深浅全部(仅 App 主题为跟随系统时)Android 12 起由系统按夜间模式选色,不用推;Android 12 以下颜色在生成时就定了,要在 uiMode 变化后重推一次
榜单内容榜单WorkManager 每 12 小时一次、需联网;打开 App 时顺带刷新。Glance 本身已依赖 WorkManager,不新增依赖
登录状态听歌模式、榜单、歌单账号页登录或退出后触发
定时关闭正在播放倒计时用 Chronometer 倒数(Android 7 起);Android 6 只显示到分钟,每分钟推一次

点了做什么

位置动作实现
播放、上一首、下一首后台执行和媒体通知的按钮走同一条路:向 PlaybackService 发媒体按键 Intent。点击组件属于用户交互,允许从后台启动前台服务
收藏后台执行actionRunCallback 写库后刷新组件
榜单行、歌单行、听歌模式播放后台起播actionRunCallback 带上歌单 ID 和序号,交给 Service 侧的起播命令
封面、标题、歌词打开页面actionStartActivity 打开 MainActivity,extra 指定 player 或 lyrics
搜索条、识曲、定时、去登录打开页面同上,extra 为 search、recognize、timer、login
榜单标题、歌单标题打开页面同上,extra 为 chart 或 collection 加 ID

先补的底层能力

  • App 没运行时也能播。现在播放队列不落盘,PlaybackService 也没有实现 onPlaybackResumption,进程被杀后点组件的播放键没有东西可放。要保存最后的队列、序号和进度,并实现这个回调;Android 13 起系统媒体控件的“继续播放”也靠它。Media3 1.11 在播放器为空时收到媒体按键是否会走这个回调,要真机确认。
  • 当前形状放到播放层。随机形状现在由 CoverStage 在界面里抽,App 没打开时组件拿不到。改成切歌时由播放层抽好,和歌曲一起保存,播放页和组件读同一个值。
  • 按歌单起播挪出 ViewModel。playCollection 在 MusicViewModel 里,组件点歌单行时 ViewModel 不一定存在。要挪到 Service 也能调用的仓库层。
  • 打开指定页面。MainActivity 读取启动 Intent 里的目标页,冷启动和已在前台两种情况都要处理。

封面位图

在 App 进程里用 Coil 按组件尺寸取图(coverAt(px),最大 480px),用 CoverShapes 的同一个多边形裁好再传给桌面。系统限制一份 RemoteViews 的位图总量不超过屏幕像素 × 4 × 1.5 字节,480px 的封面约 0.9MB,余量很大。

配色

种子色和 App 取法相同(CoverSeedRepository、wallpaperSeed()、品牌色、自选颜色),用 MaterialKolor 按浏览页配色风格、对比度、纯黑背景生成。主题跟随系统时经 ColorProviders(light, dark) 传两套;主题固定时两个位置传同一套。不用系统动态色,免得组件和 App 的颜色对不上。

计时文字

Glance 没有包装 Chronometer,用 AndroidRemoteViews 嵌一个 XML 布局,设置开始时间和是否在走。

预览图

Android 11 及以下用 previewImage 的 PNG;Android 12 起用 previewLayout;Android 15 起再提供实时生成的预览。

配置页

歌单、榜单、听歌模式、歌词有配置页,带默认值,添加时可以跳过;之后长按组件重新配置。配置页用 App 的主题。

无障碍

每个按钮都写 contentDescription,播放键同时带状态(“暂停,正在播放”)。整块组件不加点击描述,免得读屏把按钮吞掉。

平板和电视

平板桌面的格子更大,用同一组断点,最大可拉到 5×4。Android TV 没有桌面小组件,电视端不做。

国产桌面

MIUI / HyperOS、ColorOS、OriginOS 对标准小组件的圆角、尺寸和刷新频率各有处理,收尾时要逐台真机看。

工作量

要做的四组事

按依赖关系分组:后三组都建立在第一组的配色、取图和冷启动播放上。先做哪组不在这份方案里定。

基础

底层能力 + 正在播放

  • 队列落盘和 onPlaybackResumption;当前形状挪到播放层;MainActivity 打开指定页面
  • 组件配色管线(读 App 外观设置,按主题给一套或两套)、封面取图裁形状、事件合并刷新
  • 正在播放 7 档布局,加继续播放、无历史、封面加载中、定时关闭四个状态
依赖基础

歌词 + 快捷入口

  • 歌词三档、三种背景、翻译开关;亮屏判断和行变化节流
  • 快捷入口三档;识曲、搜索、定时的打开路径
依赖基础

歌单 + 听歌模式

  • 按歌单起播挪到仓库层,加 Service 侧起播命令
  • 两款的配置页,未登录状态
依赖后台起播

榜单 + 收尾

  • 榜单组件和 WorkManager 定时刷新,离线状态
  • 三代预览图;读屏走查;国产桌面真机测试
已定

四个决定

2026-10-31 确认,上面各节已经按这些改过。

1. 深浅色跟 App 的主题设置App 设成跟随系统时随手机切换;设成浅色或深色时组件固定,不管手机是什么模式。纯黑背景、配色来源、配色风格、对比度也都读 App 的外观设置。
2. 做歌词组件只在亮屏时按行刷新,不做逐字高亮,灭屏不推。播放时大约每 4 秒推一次。
3. 进度条2×3、4×2、4×3 显示,亮屏且在播放时每 10 秒推一次;时间文字由 Chronometer 每秒自己走。
4. 透明背景只给歌词其余组件提供实色和半透明两种:它们有按钮,透明后按钮压在壁纸上不好认。