创建内容会随时间推移而变化的磁贴。
使用时间线
时间线由一个或多个 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); }
基于时间的 Timeline 条目
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 入门