创建内容会随时间推移发生变化的功能块。
使用时间轴
时间轴由一个或多个 TimelineEntry 实例组成,每个实例中包含在特定间隔时间显示的布局。所有卡片都需要时间轴。
功能块时间轴图表
单条目卡片
通常,可以使用单个 TimelineEntry 来描述功能块。布局是固定不变的,只有布局中的信息会发生变化。例如,显示当天健身进度的功能块会始终显示相同的进度布局,但您可以调整该布局以显示不同的值。在此类情况下,您不会事先知道内容何时会发生变化。
下面是包含单个 TimelineEntry 的功能块示例:
Kotlin
override fun onTileRequest(
requestParams: TileRequest
): ListenableFuture<Tile> {
val tile = Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
// We add a single timeline entry when our layout is fixed, and
// we don't know in advance when its contents might change.
.setTileTimeline(
Timeline.fromLayoutElement(...)
).build()
return Futures.immediateFuture(tile)
}
Java
ListenableFuture<Tile> onTileRequest(
TileRequest requestParams
) {
Tile tile = new Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
// We add a single timeline entry when our layout is fixed, and
// we don't know in advance when its contents might change.
.setTileTimeline(
Timeline.fromLayoutElement(...)
).build();
return Futures.immediateFuture(tile);
}
protected
有时限的时间轴条目
TimelineEntry 可以选择性定义一个有效期,以允许功能块在某个已知时间更改其布局,而无需应用推送新的功能块。
一个典型的例子就是日程功能块,其时间轴包含一系列即将进行的活动。每个即将进行的活动都包含一个有效期,用于指示何时显示相应活动。
Tiles API 支持有效期重叠,在这种情况下,剩余时间最短的屏幕就是当前所显示的屏幕。一次只能显示一个事件。
开发者可以提供默认后备条目。例如,日程功能块可将一个具有无限有效期的功能块作为后备,如果没有其他有效的时间轴条目,就使用该功能块,如以下代码示例所示:
Kotlin
public override fun onTileRequest(
requestParams: TileRequest
): ListenableFuture<Tile> {
val timeline = Timeline.Builder()
// Add fallback "no meetings" entry
// Use the version of TimelineEntry that's in androidx.wear.protolayout.
timeline.addTimelineEntry(TimelineEntry.Builder()
.setLayout(getNoMeetingsLayout())
.build()
)
// Retrieve a list of scheduled meetings
val meetings = MeetingsRepo.getMeetings()
// Add a timeline entry for each meeting
meetings.forEach {
meeting ->
timeline.addTimelineEntry(TimelineEntry.Builder()
.setLayout(getMeetingLayout(meeting))
.setValidity(
// The tile should disappear when the meeting begins
// Use the version of TimeInterval that's in
// androidx.wear.protolayout.
TimeInterval.Builder()
.setEndMillis(meeting.dateTimeMillis).build()
).build()
)
}
val tile = Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setTileTimeline(timeline.build())
.build()
return Futures.immediateFuture(tile)
}
Java
ListenableFuture<Tile> onTileRequest(
RequestBuilders.TileRequest requestParams
) {
Timeline.Builder timeline = new Timeline.Builder();
// Add fallback "no meetings" entry
// Use the version of TimelineEntry that's in androidx.wear.protolayout.
timeline.addTimelineEntry(new TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build());
// Retrieve a list of scheduled meetings
List<Meeting> meetings = MeetingsRepo.getMeetings();
// Add a timeline entry for each meeting
for(Meeting meeting : meetings) {
timeline.addTimelineEntry(new TimelineEntry.Builder()
.setLayout(getMeetingLayout(meeting))
.setValidity(
// The tile should disappear when the meeting begins
// Use the version of TimeInterval that's in
// androidx.wear.protolayout.
new TimeInterval.builder()
.setEndMillis(meeting.getDateTimeMillis()).build()
).build()
);
}
Tile tile = new Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setTileTimeline(timeline.build())
.build();
return Futures.immediateFuture(tile);
}
protected
刷新功能块
功能块上显示的信息可能会在一段时间后过期。例如,天气功能块如果全天显示相同的温度并不准确。
如需处理过期数据,请在创建功能块时设置新鲜度间隔时间,用于指定功能块的有效时长。在天气功能块示例中,您可能每小时更新一次内容,如以下代码示例所示:
Kotlin
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
Futures.immediateFuture(Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
.setTileTimeline(Timeline.fromLayoutElement(
getWeatherLayout())
).build()
)
Java
ListenableFuture<Tile> onTileRequest(
TileRequest requestParams
) {
return Futures.immediateFuture(new Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
.setTimeline(Timeline.fromLayoutElement(
getWeatherLayout())
).build());
}
protected
设置新鲜度间隔时间后,系统会在间隔时间结束后立即调用 onTileRequest()。如果未设置新鲜度间隔时间,则系统不会调用 onTileRequest()。
功能块还可能因外部事件而过期。例如,用户可能会从自己的日历中移除某次会议;如果相应的功能块未刷新,那么该功能块仍会显示已删除的会议。在这种情况下,可以从应用代码中的任意位置请求刷新,如以下代码示例所示:
Kotlin
fun eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService::class.java)
}
Java
public void eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService.class);
}
选择更新工作流
您可以参考这些最佳实践来确定如何配置功能块更新:
如果是可预测的更新(例如,如果是用户日历中的下一个活动),请使用时间轴。
提取平台数据时,请使用数据绑定,以便系统自动更新数据。
如果可在短时间内在设备上计算出更新(例如在日出功能块中更新图片的位置),请使用 onTileRequest()。
如果您需要提前生成所有图片,这种做法尤其有用。如果您需要在未来生成新图片,请调用 setFreshnessIntervalMillis()。
如果您反复执行更密集的后台工作(例如轮询天气数据),请使用 WorkManager 并将更新推送到功能块。
如果更新是对外部事件(例如开灯、接收电子邮件或更新备注)的响应,请发送 Firebase Cloud Messaging (FCM) 消息,让应用恢复活跃状态,然后将更新推送到功能块。
如果功能块数据同步过程占用大量资源,请执行以下操作:
安排数据同步。
启动 1-2 秒的定时器。
如果您在时间耗尽之前从远程数据源收到更新,则显示数据同步中已更新的值。否则,显示已缓存的本地值。
目前没有任何推荐文档页面。
请尝试登录您的 Google 账号。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2023-11-22。