接口参考

星河岛 SDK 0.1.2 全部公开接口,位于 com.astraisland.sdk 包。签名以 Kotlin 书写;Java 中属性对应 getXxx() / isXxx(),带默认值的参数提供多个重载,工厂方法为静态方法。

以下签名以 Kotlin 书写;Java 中属性对应 getXxx() / isXxx(),带默认值的参数提供多个重载,工厂方法为静态方法。

IslandClient

class IslandClient(context: Context)

星河岛客户端。context 可为任意上下文,客户端只保留其应用上下文。

成员说明
enum class State { NOT_INSTALLED, WAITING, REJECTED, READY }连接状态,见下表
val state: State当前连接状态。创建后为 WAITING
val isReady: Boolean是否已连接,可以显示内容
fun setCallback(callback: IslandCallback?)设置回调;为 null 时不再接收回调
fun isHostInstalled(): Boolean设备上是否安装了可用的星流(通信版本 7)
fun connect()连接星河岛。未安装可用的星流时状态变为 NOT_INSTALLED;否则为 WAITING,星河岛响应后变为 READY。已连接时再次调用会重新连接
fun disconnect()断开连接,并结束本应用在星河岛上的全部内容
fun start(activity: IslandActivity): IslandResult显示一条内容;同一内容编号已在显示时整份替换。未连接时返回 NOT_CONNECTED
fun update(activity: IslandActivity): IslandResult与 start 相同
fun end(id: String, outro: Outro? = null): IslandResult结束一条内容,可带收尾
fun endAll(): IslandResult结束本应用在星河岛上的全部内容;未连接时返回 NOT_CONNECTED
fun listMine(): List<String>本应用仍在星河岛上的内容编号(含暂未显示、排在后面的内容);未连接时为空列表
const val SDK_VERSION: String = "0.1.2"伴生常量
const val PROTOCOL_VERSION: Int = 7伴生常量
State 取值含义
NOT_INSTALLED未安装星流,或已安装的星流不支持当前通信版本
WAITING正在等待星河岛响应;连接后长时间停留在此状态,说明星河岛未启用或设备尚未就绪(OPPO、一加、realme 手机上也可能是尚未启用插件「流体云事件接入」)
REJECTED星河岛拒绝了连接(例如身份核对未通过)
READY已连接,可以显示内容

IslandCallback

abstract class IslandCallback

按需重写,所有方法默认不做任何处理,都在主线程调用。事件尽力送达,不作为业务依据。

方法触发时机
open fun onStateChanged(state: IslandClient.State)连接状态变化
open fun onAction(activityId: String, actionId: String)用户点击了卡片上的按钮。actionId 为应用设置的按钮编号,或 TimerControl.actionId、MediaControl.actionId、StatusCard.ACTION_STOP
open fun onReply(activityId: String, text: String)用户在消息卡片的回复输入框中发送了文字。星河岛交出文字后卡片提示「已交给应用发送」;实际发送由应用负责,发送后可用同一内容编号更新卡片
open fun onSeek(activityId: String, positionMs: Long)用户在音乐卡片上拖动进度条并松手,positionMs 为毫秒。跳到该位置后,请用同一内容编号更新播放进度
open fun onDismissed(activityId: String)用户在胶囊上划动,把这条内容从星河岛上收起。内容并未结束:有真实的新消息或新的重要提醒、用户进出一次本应用,或用户点击摄像头区域召回时,它会重新显示;普通进度刷新、换歌词等重复更新不视为新的提醒。用户开启「长时间未操作时收起」或「停留后收起」后,星河岛也会在设定时间内没有操作时自动收起内容,此情形不调用本方法。不再需要时请调用 end()
open fun onExpanded(activityId: String)这条内容的卡片展开(包括用户操作与自动提醒)
open fun onCollapsed(activityId: String)这条内容的卡片收起
open fun onEnded(activityId: String, reason: EndReason)这条内容被星河岛结束
enum class EndReason { EXPIRED, REMOVED }
EndReason 取值含义
EXPIRED到达自动消失时间,或显示满 8 小时
REMOVED用户在星流中关闭了本应用的内容或音乐内容,或星河岛停止运行

IslandResult

enum class IslandResult { OK, IMAGE_REJECTED, NO_PERMISSION, SOURCE_DISABLED, KIND_DISABLED, QUOTA_EXCEEDED, RATE_LIMITED, INVALID, BUSY, NOT_CONNECTED }
取值含义
OK已受理
IMAGE_REJECTED已受理,但有图片不符合要求而未显示,其余内容照常显示
NO_PERMISSION没有投送权限:清单中缺少 SDK 自带的权限声明
SOURCE_DISABLED用户在星流中关闭了本应用的内容
KIND_DISABLED用户在星流中关闭了「星河岛歌词」,音乐卡片不予显示
QUOTA_EXCEEDED本应用通过 SDK 提交且尚未结束的内容已达 3 条,排队内容也计入;请先结束旧内容
RATE_LIMITED提交过于频繁(每秒超过 10 次),本次未受理
INVALID内容无效(例如数值不是有限数),或连接尚未就绪;原有内容保持不变
BUSY星河岛暂时繁忙,本次未处理,请稍后重试
NOT_CONNECTED尚未连接到星河岛,或连接已断开

val accepted: Boolean:是否已受理(OK 或 IMAGE_REJECTED)。受理不等于已显示,例如本应用在前台、排位靠后时内容暂不显示。

IslandActivity

class IslandActivity   // 通过 IslandActivity.Builder 生成
class IslandActivity.Builder(id: String, capsule: Capsule, card: IslandCard)

放上星河岛的一条内容。id 为内容编号,本应用内唯一,1 至 128 个字符(不能为空白)。

Builder 方法默认值说明
setPriority(priority: Priority)DEFAULT排位参考。消息卡片不使用此项,按新消息排位
setAlertOnStart(alert: Boolean)false首次显示时自动展开卡片片刻。同一应用 10 秒内最多自动展开一次
setAlertOnUpdate(alert: Boolean)false更新(且内容有变化)时自动展开卡片片刻。同一应用 10 秒内最多自动展开一次;连续更新显示最新内容,期间提出的展开要求保留一次
setLockScreenVisibility(visibility: LockScreenVisibility)PUBLIC锁屏时显示多少
setOpenIntent(intent: PendingIntent?)null点击卡片时执行的操作
setOwnNotification(id: Int, tag: String? = null)未设置说明这条内容对应本应用自己的哪一条通知(NotificationManager.notify 的编号与标签)。这条内容在星河岛上时,那条通知不再单独显示在星河岛上;内容显示在主岛或副岛上,且用户开启「屏蔽系统横幅」时,那条通知也不再弹出系统横幅。仅可关联星河岛所在用户中本应用自己的通知;内容结束后不重新显示旧通知,待通知下次更新时按通知规则处理
setPostedAt(timeMillis: Long)未设置发送时间(System.currentTimeMillis() 口径,大于 0)。显示来源栏时,卡片来源栏右侧显示「刚刚」「5 分钟前」或具体时刻;消息卡片以发送时间区分新消息
setStaleAt(timeMillis: Long)未设置过时时间(大于 0)。过了这个时间卡片注明「信息可能已过时」,内容仍保留
setDismissPolicy(policy: DismissPolicy)untilEnded()消失方式
setLandscapeText(text: String?)null横屏胶囊的完整短文字,最多 32 个字符,数字与英文按组竖排后须在四行以内;未设置或无法完整显示时,星河岛保留完整数值或短状态,不截取卡片标题。消息显示应用名称;音乐优先显示波形;空白及非文字的右侧内容保持原有形式
setAccentColor(color: Int?)null强调色(ARGB),用于进度条、主要按钮、放大的数值等;过暗的颜色会被提亮
setContentDescription(text: String?)null无障碍读屏说明,最多 256 个字符
build(): IslandActivity生成内容

异常:Builder(...) 在编号为空白或超过 128 个字符时抛出 IllegalArgumentException;setPostedAt、setStaleAt 在时间不大于 0 时抛出;setLandscapeText、setContentDescription 在文字为空白或超长时抛出;build() 在全部文字合计超过 8192 字节(UTF-8)时抛出。

只读属性:id、capsule、card、priority、alertOnStart、alertOnUpdate、lockScreenVisibility、openIntent、notificationId: Int?、notificationTag: String?、postedAtMillis: Long?、staleAtMillis: Long?、dismissPolicy、landscapeText、accentColor、contentDescription。

enum class Priority { LOW, DEFAULT, HIGH }
取值含义
LOW低:排在正在播放的音乐之后
DEFAULT默认:按卡片种类(计时、进度、音乐等)的默认排位
HIGH高:外部应用内容的最高档,与未到点的计时同档
enum class LockScreenVisibility { PUBLIC, TITLE_ONLY, HIDDEN }
取值含义
PUBLIC完整显示。设置了 requiresUnlock 的按钮仍在锁屏时隐藏,回复输入框锁屏时不显示
TITLE_ONLY只显示标题与头像等图片:说明、正文、码、明细、比分、数值、标签、阶段名、按钮与大图均不显示
HIDDEN锁屏时不显示
class DismissPolicy
  companion object {
    fun untilEnded(): DismissPolicy          // 一直显示,直到应用调用 end();最长 8 小时
    fun afterMillis(millis: Long): DismissPolicy  // 显示后经过给定时长(大于 0,否则抛出 IllegalArgumentException)自动消失
  }
class Outro(val success: Boolean, val text: String)

结束内容时可选的收尾:胶囊上显示对勾(success = true)或叉号和一句话,约 1.6 秒后消失;只在这条内容仍在星河岛上时显示。text 为空白或超过 128 个字符时抛出 IllegalArgumentException。

Capsule

class Capsule   // 通过 Capsule.Builder 生成
class Capsule.Builder(leading: IslandImage)

胶囊:左侧一张图片(必填),可跟一段小标题;右侧一项信息;最右端可再固定一个小图或进度环。

Builder 方法默认值说明
setLabel(label: String?)null左侧图片右边的小标题,最多 32 个字符
setTrailing(trailing: CapsuleTrailing?)null右侧信息;为 null 时右侧留空
setTail(tail: CapsuleTail?)null固定在胶囊最右端的小图或进度环;横屏时不显示
setBreathing(breathing: Boolean)false左侧图标做明暗呼吸变化(3 秒一轮),表示正在进行中。照片类图片不支持
setLeadingTint(color: Int?)null左侧内置符号的颜色(ARGB),仅对 IslandImage.symbol 生效
setSatellite(satellite: Satellite?)null副岛内容;为 null 时显示左侧图片
build(): Capsule照片类图片设置了呼吸变化,或非内置符号设置了颜色时抛出 IllegalArgumentException

只读属性:leading、leadingTint、breathing、label、trailing、tail、satellite。

CapsuleTrailing(胶囊右侧信息,静态工厂方法;颜色为 ARGB,null 时使用胶囊文字颜色或强调色,过暗的颜色会被提亮):

方法说明
text(text: String, color: Int? = null)文字,放不下时滚动显示,最多 512 个字符
number(text: String, color: Int? = null)数字等宽显示,适合频繁变化的数值(例如「12 km」「45%」),最多 512 个字符
countdown(endAtMillis: Long, color: Int? = null)倒计时,由星河岛逐秒走动,到点停在 00:00。endAtMillis 为结束时刻(大于 0)
stopwatch(startedAtMillis: Long, color: Int? = null)正计时,由星河岛逐秒走动。startedAtMillis 为开始时刻(大于 0)
progress(fraction: Float, color: Int? = null)进度环,fraction 为 0 至 1
busy(color: Int? = null)忙碌指示:转圈的亮弧,用于没有具体进度的进行中状态
waveform(active: Boolean = true, color: Int? = null)跳动线条,用于声音、通话等持续进行的活动;active = false 时静止

CapsuleTail(胶囊最右端,静态工厂方法):image(image: IslandImage);progress(fraction: Float, color: Int? = null)(fraction 为 0 至 1)。

Satellite(副岛内容,静态工厂方法):image(image: IslandImage);progress(fraction: Float, image: IslandImage? = null, color: Int? = null)(进度环,环中间可放一张图片)。

以上工厂方法在文字为空白或超长、时间不大于 0、比例不在 0 至 1 之间(含非有限数)时抛出 IllegalArgumentException。

IslandImage 与 BuiltinSymbol

class IslandImage
  companion object {
    fun picture(bitmap: Bitmap): IslandImage   // 照片类图片:头像、封面、商品图、截图,按原图显示
    fun glyph(bitmap: Bitmap): IslandImage     // 单色图标:按内置符号样式显示(卡片上带圆形浅色底,胶囊中不加描边)
    fun symbol(symbol: BuiltinSymbol): IslandImage  // 星河岛内置符号
    fun appIcon(): IslandImage                 // 本应用的桌面图标,仅用于胶囊与副岛
  }
  val isAppIcon: Boolean
  val isPicture: Boolean

位图须满足:未被回收;宽和高均在 1 至 2048 像素之间;占用内存(Bitmap.getAllocationByteCount())不超过 8 MB(8388608 字节)。不满足时 picture、glyph 抛出 IllegalArgumentException。

卡片上的图片(卡片左图、头像、标题小图、进度小图、对称标志)不接受 appIcon():显示来源栏时,来源栏已显示应用图标与名称;用户关闭「显示应用来源」且卡片没有内容图片时,星河岛在卡片左侧显示应用图标。

enum class BuiltinSymbol:MUSIC(音乐)、TIMER(计时器)、ALARM(闹钟)、BATTERY(电池)、BOLT(闪电)、HEADPHONES(耳机)、BLUETOOTH(蓝牙)、MESSAGE(消息)、CHECK(对勾)、CLOSE(叉号)、PLAY(播放)、PAUSE(暂停)、SKIP_NEXT(下一首)、SKIP_PREV(上一首)、NAVIGATION(方向箭头)、HOURGLASS(沙漏)、INFO(提示)、DOWNLOAD(下载)。

IslandCard(展开卡片)

sealed class IslandCard { abstract val title: String }

九种子类:GenericCard、ProgressCard、EmphasisCard、DetailsCard、StatusCard、PictureCard、MediaCard、MessageCard、MirrorCard,均通过各自的 Builder 生成。

所有卡片的共同规则:

GenericCard(通用)

左侧图片,标题(右侧可放大显示一项数值或时间),说明一行,正文最多两行,底部按钮。

GenericCard.Builder(title: String)

方法说明
setSubtitle(subtitle: String?)说明,最多 256 个字符
setBody(body: String?)正文,最多 4096 个字符,卡片上最多显示两行
setImage(image: IslandImage?)左侧图片
setValue(value: CardValue?)标题右侧放大显示的一项
setTag(tag: CardTag?)说明后面的小标签
setTitleMark(mark: IslandImage?)标题后面的小图(例如完成时的对勾)
addButton(button: IslandButton) / setButtons(buttons: List<IslandButton>)添加一个按钮 / 替换全部按钮;可用 TextButton、IconButton、BarIconButton、ToggleButton
build(): GenericCard按钮种类或数量超出上限、编号重复时抛出 IllegalArgumentException

属性:title、subtitle、body、image、value、tag、titleMark。

CardValue(静态工厂方法):text(text: String, color: Int? = null, icon: IslandImage? = null)(数值,最多 32 个字符;颜色为 null 时使用强调色,过暗的颜色会被提亮;icon 为数值前的小图);countdown(endAtMillis: Long);stopwatch(startedAtMillis: Long)。

CardTag:CardTag(text: String?, icon: IslandImage? = null)。文字最多 32 个字符;文字与图标都为 null 时抛出 IllegalArgumentException。属性:text、icon。

ProgressCard(进度)

左侧图片,标题(右侧自动显示百分比),说明与正文,底部一条进度条;进度条可分阶段并在下方写阶段名,也可带一个随进度移动的小图(例如骑手)。适用于外卖、打车、下载、上传等。

ProgressCard.Builder(title: String)

方法说明
setSubtitle(subtitle: String?)说明,最多 256 个字符
setBody(body: String?)正文,最多 4096 个字符,卡片上显示一行
setImage(image: IslandImage?)左侧图片
setProgress(fraction: Float)确定的进度,0 至 1
setIndeterminate()进度不确定:进度条上一段亮条来回移动
setLabels(start: String?, end: String?)进度条下方左端与右端的文字,各最多 32 个字符;设置了阶段名时不可用
setStages(stages: List<String>)各阶段名称,2 至 16 个(传空列表表示清除),每个最多 32 个字符。进度条按阶段数平均分段、在分界处画节点;三个以上阶段时每个名称写在对应节点下方,两个阶段时写在两端
setMarker(marker: IslandImage?)随进度移动的小图(例如骑手、车辆),显示在强调色圆形底上
addButton / setButtons可用 TextButton、IconButton、BarIconButton、ToggleButton
build(): ProgressCard未调用 setProgress 或 setIndeterminate;阶段名与两端文字同时设置;进度不确定时设置了阶段名;按钮超出上限时抛出 IllegalArgumentException

属性:title、subtitle、body、image、fraction: Float?(null 表示进度不确定)、startLabel、endLabel、stages: List<String>、marker。

EmphasisCard(强调)

一张卡里最要紧的一串码或一段计时放大显示。

EmphasisCard.Builder(title: String, value: EmphasisValue)

方法说明
setSubtitle(subtitle: String?)说明,最多 256 个字符
setBody(body: String?)正文,最多 4096 个字符
setImage(image: IslandImage?)左侧图片
addControl(control: TimerControl)添加一个计时控制按钮,仅计时可用,按加入顺序排列
addButton / setButtons可用 TextButton、IconButton、BarIconButton、ToggleButton
build(): EmphasisCard码设置了计时控制按钮,或按钮超出上限时抛出 IllegalArgumentException

属性:title、value、subtitle、body、image、controls: List<TimerControl>。

EmphasisValue(静态工厂方法):code(text: String)(最多 32 个字符);countdown(endAtMillis: Long)(到点停在 00:00);stopwatch(startedAtMillis: Long);paused(durationMillis: Long)(已暂停的计时,静止显示给定时长,格式 mm:ss,满一小时为 h:mm:ss;时长不能为负数)。属性 isTimer: Boolean:是否为计时。

DetailsCard(明细)

通用卡片的排布,底部并排若干格(上方名称、下方数值),例如违章的车牌与时间、电影的场次与座位。

DetailsCard.Builder(title: String)

方法说明
setSubtitle / setBody / setImage同通用卡片
addDetail(detail: CardDetail) / addDetail(label: String, value: String)添加一格明细
setTag(tag: CardTag?)说明后面的小标签
setTitleMark(mark: IslandImage?)标题后面的小图
addButton / setButtons可用 TextButton、IconButton、BarIconButton、ToggleButton
build(): DetailsCard明细不在 1 至 6 格之间,或按钮超出上限时抛出 IllegalArgumentException

属性:title、subtitle、body、image、details: List<CardDetail>、tag、titleMark。

CardDetail:CardDetail(label: String, value: String),名称与数值各最多 32 个字符。属性:label、value。

StatusCard(状态)

左侧图片,标题与说明,右侧放大显示一项数值或正计时,底部可带一条电量式的水平条;正文写在下方,最多两行。适用于设备连接、运行状态等。

StatusCard.Builder(title: String)

方法说明
setSubtitle / setBody / setImage同通用卡片
setValue(value: StatusValue?)右侧放大显示的一项
setLevel(level: Float?)底部水平条的比例,0 至 1
setStopButton(show: Boolean)显示红色停止圆钮;点击后 onAction 收到按钮编号 StatusCard.ACTION_STOP("stop")
addButton / setButtons可用 TextButton、IconButton、BarIconButton、ToggleButton
build(): StatusCard按钮超出上限时抛出 IllegalArgumentException(停止圆钮计入圆形按钮)

属性:title、subtitle、body、image、value、level: Float?、stopButton: Boolean。伴生常量:const val ACTION_STOP: String = "stop"。

StatusValue(静态工厂方法):text(text: String)(最多 32 个字符,例如「85%」「已连接」);stopwatch(startedAtMillis: Long)。

PictureCard(大图)

标题与一行正文,下方一张铺满卡片宽度的大图(最高约 140dp,超出部分居中裁切)。只有一个文字按钮时,按钮显示在标题右侧。锁屏只显示标题时不显示大图。

PictureCard.Builder(title: String, picture: IslandImage):picture 须为 IslandImage.picture,否则抛出 IllegalArgumentException。

方法说明
setBody(body: String?)正文,最多 4096 个字符,卡片上显示一行
addButton / setButtons可用 TextButton、BarIconButton、ToggleButton
build(): PictureCard使用了圆形图标按钮,或按钮超出上限时抛出 IllegalArgumentException

属性:title、picture、body。

MediaCard(音乐)

左侧封面,歌名与歌手,一行歌词,播放按键与进度条。进度由星河岛按播放状态与速度自行推进。播放按键排在右侧或歌词下方,由用户在星流「星河岛歌词」页选择的「音乐卡片样式」决定,应用无需处理。

MediaCard.Builder(title: String):title 为歌名,最多 128 个字符。

方法说明
setArtist(artist: String?)歌手,最多 256 个字符
setCover(cover: IslandImage?)封面,须为 IslandImage.picture;为 null 时显示音符占位
setPlaying(playing: Boolean)是否正在播放:决定播放键的图形与进度是否走动。默认 false
setProgress(durationMillis: Long, positionMillis: Long, atMillis: Long = System.currentTimeMillis(), speed: Float = 1f)播放进度:总时长大于 0;位置在 0 至总时长之间;atMillis 为取得位置的时刻(大于 0);速度在 -16 至 16 之间
setLyric(lyric: String?)当前一句歌词,最多 512 个字符;为 null 时歌词行留空
addControl(control: MediaControl)仅加入应用实际支持的播放操作;未加入的按键不可操作
setSeekable(seekable: Boolean)进度条可拖动,松手位置由 onSeek 交给应用。须先设置播放进度
build(): MediaCard可拖动但未设置播放进度时抛出 IllegalArgumentException

属性:title、artist、cover、playing、durationMillis: Long?、positionMillis: Long?、positionAtMillis: Long?、playbackSpeed: Float、lyric、controls: Set<MediaControl>、seekable。音乐卡片不接受其他按钮。

MessageCard(消息)

左侧头像,发送者与最新一条消息(最多两行),可带回复输入框与按钮。消息卡片按新消息排位:刚送达时优先显示在主岛,停留一段时间后让位;设置了发送时间时,发送时间变化才算新的一条,未设置时标题或消息内容变化才算。

MessageCard.Builder(sender: String, text: String):发送者最多 128 个字符;消息内容最多 4096 个字符,卡片上最多显示两行。

方法说明
setAvatar(avatar: IslandImage?)头像
setReplyEnabled(enabled: Boolean)显示回复输入框,用户发送的文字由 onReply 交给应用;锁屏时不显示输入框。编辑或发送期间,新消息不替换当前回复卡片;未交给应用的文字保留为草稿
addButton / setButtons可用 TextButton、BarIconButton、ToggleButton
build(): MessageCard使用了圆形图标按钮,或按钮超出上限时抛出 IllegalArgumentException

属性:title(发送者)、text、avatar、replyEnabled。

MirrorCard(对称)

左右两侧各写一个名称(可带标志与小字),中间放大显示两侧的比分,下方一行写比赛信息。尚无比分时,中间放大显示 setCenterText 设置的文字(例如「19:30 开赛」)。卡片不显示按钮。

MirrorCard.Builder(title: String, left: MirrorSide, right: MirrorSide):title 不单独显示在卡片上,用于无障碍读屏。

方法说明
setCenterText(text: String?)尚无比分时中间放大显示的文字,最多 32 个字符;设置后不显示比分
setDetail(detail: String?)下方一行小字(例如赛事与比赛阶段),最多 128 个字符
build(): MirrorCard未设置中间文字时两侧缺少比分,抛出 IllegalArgumentException

属性:title、left、right、centerText、detail。

MirrorSide:MirrorSide(name: String, score: String? = null, logo: IslandImage? = null, note: String? = null)。名称、比分、小字各最多 32 个字符;logo 为名称上方的标志。属性:name、score、logo、note。

按钮

sealed class IslandButton(val id: String, val requiresUnlock: Boolean)

用户点击后,onAction 收到内容编号与按钮编号。requiresUnlock = true 时,锁屏状态下隐藏此按钮。

按钮编号:非空白,最多 64 个字符,同一张卡片内不得重复;不得使用 SDK 保留的编号 pause、resume、stop、toggle、prev、play_pause、next。违反时构造方法或 build() 抛出 IllegalArgumentException。

类构造方法说明
TextButtonTextButton(id: String, label: String, style: ButtonStyle = NORMAL, icon: IslandImage? = null, fillColor: Int? = null, requiresUnlock: Boolean = false)文字按钮,可在文字前带小图标。排在卡片底部,默认每排三个、最多四个,排法见「按钮排法」。label 最多 32 个字符。fillColor 为自定义底色(ARGB),仅 NORMAL 样式可用:不透明度过半为实心底,否则为浅色底;白色、完全透明或在深色卡片上看不清的深色按普通灰色底显示
IconButtonIconButton(id: String, icon: IslandImage, description: String, requiresUnlock: Boolean = false)圆形图标按钮,显示在卡片第一行右侧,灰色圆形底。description 为读屏说明,最多 32 个字符
BarIconButtonBarIconButton(id: String, icon: IslandImage, description: String, requiresUnlock: Boolean = false)底部图标按钮:只有图标、没有文字,在卡片底部另起一排并列显示。description 最多 32 个字符
ToggleButtonToggleButton(id: String, label: String, checked: Boolean, icon: IslandImage? = null, requiresUnlock: Boolean = false)开关按钮:在卡片底部并排成一排,打开时以强调色显示。点击后星河岛不会自行切换状态,请在 onAction 中处理后用同一内容编号更新 checked

各类属性与构造参数同名。

enum class ButtonStyle { NORMAL, PRIMARY, DESTRUCTIVE }

NORMAL:灰色底;PRIMARY:强调色实心底,用于最主要的操作;DESTRUCTIVE:浅红底红字,用于删除、取消等操作。

enum class TimerControl(val actionId: String) { PAUSE("pause"), RESUME("resume"), STOP("stop") }

计时类强调卡片右侧的圆形控制按钮:PAUSE 暂停(强调色实心圆钮),RESUME 继续(强调色实心圆钮),STOP 结束(灰色圆钮,叉号)。

enum class MediaControl(val actionId: String) { PREVIOUS("prev"), PLAY_PAUSE("play_pause"), NEXT("next") }

音乐卡片的播放按键:上一首、播放或暂停(图形随播放状态切换)、下一首。

数量上限(每张卡片):

种类上限
文字按钮 TextButton4
圆形按钮(IconButton,以及 TimerControl、状态卡片停止圆钮)3
底部图标按钮 BarIconButton4
以上三类合计4
开关按钮 ToggleButton3(另计)

各卡片可用的按钮:

卡片TextButtonIconButtonBarIconButtonToggleButton固定按钮
通用、进度、明细可用可用可用可用无
强调可用可用可用可用TimerControl(仅计时)
状态可用可用可用可用停止圆钮
大图、消息可用不可用可用可用无
音乐不可用不可用不可用不可用MediaControl
对称不可用不可用不可用不可用无

按钮的具体位置由星河岛按卡片排布决定:例如只有一个文字按钮且第一行右侧空闲时,它显示为第一行右侧的小按钮。底部文字按钮的排法可用 setButtonLayout 调整,见「按钮排法」。

按钮排法

底部带字的按钮默认每排 3 个、各占三分之一;4 个时平均分两排、各两个;一排里只剩 1 个时占半排居中。可用卡片构建器的 setButtonLayout 按卡修改,不设置时按默认排法。

class ButtonLayout @JvmOverloads constructor(
    val perRow: Int = 3,
    val rowFill: RowFill = RowFill.EQUAL,
    val loneFill: LoneFill = LoneFill.HALF,
    val loneAlign: LoneAlign = LoneAlign.CENTER,
)
参数取值说明
perRow1 至 4一排最多几个文字按钮;超出范围时构造方法抛出 IllegalArgumentException
rowFillEQUAL(默认)、WEIGHT、CONTENT一排里按钮的宽度怎么分:等分;带底色的按钮(PRIMARY 或设置了 fillColor 的文字按钮)占两份宽,其余平分剩下的宽度;按文字长短排
loneFillHALF(默认)、FULL、CONTENT一排里只剩一个按钮时占多宽:半排、整排、按文字长短
loneAlignSTART、CENTER(默认)、END只剩一个按钮时靠左、居中、靠右;loneFill = FULL 时不生效
GenericCard.Builder("停车计费")
    .addButton(TextButton("pay", "缴费", ButtonStyle.PRIMARY))
    .addButton(TextButton("later", "稍后"))
    .addButton(TextButton("detail", "详情"))
    .setButtonLayout(ButtonLayout(perRow = 3))
    .build()