Le seguenti sezioni descrivono come aggiornare GlanceAppWidget
e gestirne lo stato.
Gestisci stato GlanceAppWidget
Viene creata un'istanza della classe GlanceAppWidget
fornita ogni volta che il widget viene creato o richiede un aggiornamento, pertanto dovrebbe essere stateless e passiva.
Il concetto di stato può essere suddiviso come segue:
- Stato applicazione: lo stato o i contenuti dell'app richiesti dal widget. Ad esempio, un elenco di destinazioni archiviate (ovvero database) definite dall'utente.
- Stato Glance: lo stato specifico che è pertinente soltanto per il widget dell'app e non modifica né influisce necessariamente sullo stato dell'app. Ad esempio, nel widget è stata selezionata una casella di controllo o è stato aumentato un contatore.
Usa stato applicazione
I widget delle app devono essere passivi. Ogni applicazione è responsabile della gestione del livello dati e degli stati, come inattività, caricamento e visualizzazione degli errori nella UI del widget.
Ad esempio, il seguente codice recupera le destinazioni dalla cache in memoria dal livello del repository, fornisce l'elenco delle destinazioni archiviate e mostra una UI diversa a seconda dello stato:
class DestinationAppWidget : GlanceAppWidget() { // ... @Composable fun MyContent() { val repository = remember { DestinationsRepository.getInstance() } // Retrieve the cache data everytime the content is refreshed val destinations by repository.destinations.collectAsState(State.Loading) when (destinations) { is State.Loading -> { // show loading content } is State.Error -> { // show widget error content } is State.Completed -> { // show the list of destinations } } } }
Ogni volta che lo stato o i dati cambiano, è responsabilità dell'app avvisare e aggiornare il widget. Vedi Aggiornamento di GlanceAppWidget per ulteriori informazioni.
Aggiorna GlanceAppWidget
Come spiegato nella sezione Gestisci lo stato di GlanceAppWidget
, i widget delle app sono ospitati con un processo diverso. Glance traduce i contenuti in RemoteViews
effettivi e li invia all'host. Per aggiornare i contenuti, Glance
deve ricreare il file RemoteViews
e inviarlo di nuovo.
Per inviare l'aggiornamento, chiama il metodo update
dell'istanza GlanceAppWidget
, fornendo context
e glanceId
:
MyAppWidget().update(context, glanceId)
Per ottenere glanceId
, esegui una query su GlanceAppWidgetManager
:
val manager = GlanceAppWidgetManager(context) val widget = GlanceSizeModeWidget() val glanceIds = manager.getGlanceIds(widget.javaClass) glanceIds.forEach { glanceId -> widget.update(context, glanceId) }
In alternativa, utilizza una delle estensioni GlanceAppWidget update
:
// Updates all placed instances of MyAppWidget MyAppWidget().updateAll(context) // Iterate over all placed instances of MyAppWidget and update if the state of // the instance matches the given predicate MyAppWidget().updateIf<State>(context) { state -> state == State.Completed }
Questi metodi possono essere chiamati da qualsiasi parte dell'applicazione. Poiché sono funzioni suspend
, ti consigliamo di avviarle al di fuori dell'ambito dei thread principale. Nell'esempio seguente, vengono lanciati in un CoroutineWorker
:
class DataSyncWorker( val context: Context, val params: WorkerParameters, ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // Fetch data or do some work and then update all instance of your widget MyAppWidget().updateAll(context) return Result.success() } }
Per ulteriori dettagli sulle coroutine, vedi Kotlin Coroutines su Android.