创建包含随时间推移而变化的内容的磁贴。
使用时间线
时间线包含一个或多个 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
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull 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); }
有时间限制的时间线条目
一个 TimelineEntry
可以选择定义有效期,允许磁贴在已知时间更改其布局,而无需应用推送新的磁贴。
典型的例子是议程磁贴,其时间线包含即将发生的事件列表。每个即将发生的事件都包含一个有效期,以指示何时显示它。
磁贴 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
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull 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); }
刷新磁贴
磁贴上显示的信息可能在一段时间后过期。例如,显示全天相同温度的天气磁贴并不准确。
为了处理过期数据,在创建磁贴时设置新鲜度间隔,它指定磁贴的有效时间。在天气磁贴的示例中,您可能每小时更新其内容一次,如以下代码示例所示
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
@Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTimeline(Timeline.fromLayoutElement( getWeatherLayout()) ).build()); }
当您设置新鲜度间隔时,系统会在间隔结束后不久调用 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 秒的计时器。
- 如果您在计时器超时前从远程数据源收到更新,请显示来自数据同步的更新值。否则,显示缓存的本地值。
推荐给您
- 注意:当 JavaScript 关闭时,链接文本将显示
- 最大程度地减少定期更新的影响
- 在后台访问位置
- WorkManager 入门