Crea riquadri con contenuti che cambiano nel tempo.
Utilizzare le tempistiche
Una sequenza temporale è composta da una o più istanze TimelineEntry
, ognuna delle quali contiene un layout che viene visualizzato durante un intervallo di tempo specifico. Tutti i riquadri devono avere una sequenza temporale.
Riquadri a ingresso singolo
Spesso un riquadro può essere descritto con un singolo TimelineEntry
. Il layout è fisso e cambiano solo le informazioni al suo interno. Ad esempio, un riquadro che mostra i tuoi progressi durante la giornata mostra sempre lo stesso layout dei progressi, anche se puoi modificarlo per mostrare valori diversi. In questi casi, non sei a conoscenza in anticipo quando i contenuti potrebbero cambiare.
Vedi l'esempio seguente di un riquadro con un singolo 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); }
Voci di sequenza temporale con vincoli temporali
Un TimelineEntry
può facoltativamente definire un periodo di validità, consentendo a un riquadro di
modificare il proprio layout in un momento noto senza che l'app debba inviare un nuovo riquadro.
L'esempio canonico è un riquadro dell'agenda la cui sequenza temporale contiene un elenco di eventi imminenti. Ogni evento imminente contiene un periodo di validità per indicare quando mostrarlo.
L'API dei riquadri consente di sovrapporre periodi di validità, dove viene mostrata la schermata con il periodo di tempo più breve. Viene visualizzato un solo evento alla volta.
Gli sviluppatori possono fornire una voce di riserva predefinita. Ad esempio, il riquadro dell'agenda potrebbe avere un riquadro con un periodo di validità infinita, che viene utilizzato se nessun'altra voce della sequenza temporale è valida, come mostrato nel seguente esempio di codice:
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); }
Aggiornare un riquadro
Le informazioni mostrate su un riquadro potrebbero scadere dopo un certo periodo di tempo. Ad esempio, un riquadro meteo che mostra la stessa temperatura durante la giornata non è preciso.
Per gestire i dati in scadenza, imposta un intervallo di aggiornamento al momento della creazione di un riquadro, che specifica per quanto tempo il riquadro è valido. Nell'esempio del riquadro Meteo, puoi aggiornarne il contenuto ogni ora, come mostrato nel seguente esempio di codice:
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()); }
Quando imposti un intervallo di aggiornamento, il sistema chiama
onTileRequest()
poco dopo il suo termine. Se non imposti un intervallo di aggiornamento, il sistema non chiama onTileRequest()
.
Un riquadro può scadere anche a causa di un evento esterno. Ad esempio, un utente potrebbe rimuovere una riunione dal proprio calendario e, se il riquadro non veniva aggiornato, mostrerà comunque quella riunione eliminata. In questo caso, richiedi un aggiornamento da qualsiasi punto del codice dell'applicazione, come mostrato nel seguente esempio di codice:
Kotlin
fun eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService::class.java) }
Java
public void eventDeletedCallback() { TileService.getUpdater(context) .requestUpdate(MyTileService.class); }
Scegli un flusso di lavoro di aggiornamento
Per determinare come configurare gli aggiornamenti dei riquadri, utilizza queste best practice:
- Se l'aggiornamento è prevedibile, ad esempio per l'evento successivo nel calendario dell'utente, utilizza una sequenza temporale.
- Quando recuperi i dati della piattaforma, utilizza l'associazione di dati in modo che il sistema aggiorni automaticamente i dati.
Se è possibile calcolare l'aggiornamento sul dispositivo in un breve periodo di tempo, ad esempio aggiornare la posizione di un'immagine su un riquadro luce graduale, utilizza
onTileRequest()
.Questa opzione è particolarmente utile quando è necessario generare tutte le immagini in anticipo. Se in futuro avrai bisogno di generare una nuova immagine, chiama
setFreshnessIntervalMillis()
.Se esegui ripetutamente un lavoro in background più intensivo, ad esempio il polling per i dati meteo, utilizza
WorkManager
ed esegui il push degli aggiornamenti nel riquadro.Se l'aggiornamento è in risposta a un evento esterno, ad esempio se le luci si accendono, la ricezione di un'email o l'aggiornamento di una nota, invia un messaggio Firebase Cloud Messaggiging (FCM) per riattivare l'app, quindi invia gli aggiornamenti al riquadro.
Se il processo di sincronizzazione dei dati dei riquadri potrebbe essere costoso, procedi nel seguente modo:
- Pianificare una sincronizzazione dei dati.
- Avvia un timer di 1-2 secondi.
- Se ricevi un aggiornamento da un'origine dati remota prima che il tempo scada, mostra il valore aggiornato dalla sincronizzazione dei dati. In caso contrario, mostra un valore locale memorizzato nella cache.
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Interagire con le schede