卡片模板
九套卡片模板分别对应 IslandCard 的九个子类,均通过各自的 Builder 生成。模板的外观与适用场景见设计规范中的卡片模板。
共同规则
- 用户开启「显示应用来源」时,卡片顶部由星河岛写入本应用的图标与名称;设置了发送时间时在右侧显示时间。该开关位于星流「显示规则」页,默认关闭;关闭后不显示来源栏,卡片左侧没有内容图像时显示应用图标。
- 卡片左侧只放内容自身的图像(头像、封面、商品图、符号),不接受
IslandImage.appIcon()。用户关闭「显示应用来源」且卡片没有内容图像时,星河岛会显示应用图标。 - 文字长度按 UTF-16 字符计:标题最多 128 个,说明最多 256 个,正文最多 4096 个,其余短文字最多 32 个。
setXxx传入null表示不显示该项。文字不合规时立即抛出异常;按钮数量、必填项等组合规则在build()时检查。
通用 GenericCard

val card = GenericCard.Builder("停车计费")
.setSubtitle("B2 层 052 号")
.setValue(CardValue.text("¥12"))
.addButton(TextButton("pay", "缴费"))
.build()标题右侧可放大显示一项数值(CardValue.text)或走动的时间(CardValue.countdown、CardValue.stopwatch);说明后可带小标签(CardTag),标题后可带小图(setTitleMark)。
进度 ProgressCard

val card = ProgressCard.Builder("正在下载离线地图")
.setSubtitle("128 MB / 200 MB")
.setProgress(0.64f)
.setStages(listOf("开始", "下载", "完成"))
.addButton(TextButton("cancel", "取消"))
.build()- 必须调用
setProgress(fraction)或setIndeterminate()之一。 setStages接受 2 至 16 个阶段名;与setLabels(start, end)不能同时使用,进度不确定时不能设置阶段名。
强调 EmphasisCard


// 码
val codeCard = EmphasisCard.Builder("取件码", EmphasisValue.code("6-2-1048"))
.setSubtitle("菜鸟驿站 · 东门 3 号柜")
.build()
// 计时
val timerCard = EmphasisCard.Builder("专注", EmphasisValue.countdown(endAtMillis))
.setSubtitle("第 2 轮")
.addControl(TimerControl.PAUSE)
.addControl(TimerControl.STOP)
.build()计时可用 countdown、stopwatch 或 paused(durationMillis)。用户点按控制按钮后,onAction 收到 TimerControl.PAUSE.actionId 等编号;应用暂停计时后,用 EmphasisValue.paused(剩余时长) 与 TimerControl.RESUME 更新同一内容。码不能添加计时控制按钮。
明细 DetailsCard

val card = DetailsCard.Builder("星际穿越")
.setSubtitle("今天 19:30 开场")
.setImage(IslandImage.picture(posterBitmap))
.addDetail("影厅", "IMAX 3 号厅")
.addDetail("座位", "7 排 12 座")
.build()明细为 1 至 6 格,每格名称与数值各最多 32 个字符。
状态 StatusCard

val card = StatusCard.Builder("手环已连接")
.setSubtitle("运动记录同步中")
.setImage(IslandImage.symbol(BuiltinSymbol.BLUETOOTH))
.setValue(StatusValue.text("85%"))
.setLevel(0.85f)
.setStopButton(true)
.build()setStopButton(true) 显示红色停止圆钮,点按后 onAction 收到 StatusCard.ACTION_STOP。
大图 PictureCard

val card = PictureCard.Builder("你的照片已生成", IslandImage.picture(photoBitmap))
.setBody("点按查看全部 12 张")
.addButton(TextButton("open", "查看"))
.build()大图必须为 IslandImage.picture。大图卡片不接受圆形图标按钮;锁屏仅显示标题时不显示大图。
音乐 MediaCard

val card = MediaCard.Builder("晚风")
.setArtist("青屿")
.setCover(IslandImage.picture(coverBitmap))
.setPlaying(true)
.setProgress(durationMillis = 269_000, positionMillis = 83_000)
.setLyric("晚风掠过 屋檐下的灯")
.addControl(MediaControl.PREVIOUS)
.addControl(MediaControl.PLAY_PAUSE)
.addControl(MediaControl.NEXT)
.setSeekable(true)
.build()进度由星河岛按播放状态与速度推进,应用只需在播放状态或位置改变时更新。setSeekable(true) 需先设置播放进度;用户拖动松手后,onSeek 收到目标位置。音乐卡片不接受其他按钮。
播放按键排在右侧还是歌词下方,由用户在星流「星河岛歌词」页选择的「音乐卡片样式」决定,见设计规范中的音乐模板,应用无需处理。「卡片显示喜欢与播放设备按钮」只作用于星流自己显示的音乐卡片,不作用于本应用发送的音乐卡片。
消息与短信回复 MessageCard
短信与即时消息均使用消息模板。回复输入条由星河岛提供;「标为已读」等操作由应用声明,收到操作后由应用处理。

val card = MessageCard.Builder("小明", "晚上一起吃饭吗?")
.setAvatar(IslandImage.picture(avatarBitmap))
.setReplyEnabled(true)
.addButton(TextButton("mark_read", "标为已读"))
.build()消息卡片按新消息排位:刚送达时优先显示在主岛,停留一段时间后让位。设置了发送时间(setPostedAt)时,发送时间变化才视为新消息;未设置时,发送人或消息内容变化即视为新消息。消息卡片不接受圆形图标按钮。
setReplyEnabled(true) 开启回复入口,输入后使用右端发送键。发送文字交给 onReply;点击「标为已读」时,onAction 收到 mark_read。此编号为示例自定义值,并非系统保留操作。
完整的状态配图见回复与发送状态;处理代码见回复、发送与标为已读。示例工程仅展示操作与文字回传,不连接短信服务或聊天服务器。
对称 MirrorCard

val card = MirrorCard.Builder(
"中国队 2:1 日本队",
MirrorSide("中国队", score = "2", logo = IslandImage.picture(chinaLogo)),
MirrorSide("日本队", score = "1", logo = IslandImage.picture(japanLogo)),
)
.setDetail("世界杯预选赛 · 下半场 72'")
.build()标题不单独显示,用于无障碍读屏。尚无比分时,用 setCenterText("19:30 开赛") 代替比分。对称卡片不显示按钮。