Per migliorare l'esperienza del selettore di widget della tua app, fornisci un'anteprima del widget generata sui dispositivi con Android 15 e versioni successive, un'anteprima del widget scalata (specificando un previewLayout) per i dispositivi con Android 12-14 e un previewImage per le versioni precedenti.
Le anteprime dei widget generate ti consentono di creare anteprime dinamiche e personalizzate per i tuoi widget che riflettono con precisione il modo in cui verranno visualizzati nella schermata Home di un utente. Per Android 15 e versioni successive, vengono fornite tramite un'API push, il che significa che la tua app fornisce l'anteprima in qualsiasi momento del suo ciclo di vita senza ricevere una richiesta esplicita dall'host del widget.
Per maggiori informazioni, consulta Arricchire la tua app con aggiornamenti live e widget su YouTube.
Aggiungere anteprime generate
Per mostrare le anteprime dei widget generate su un dispositivo con Android 15 o versioni successive, imposta prima il
compileSdk valore su 35 o versioni successive nel file build.gradle del modulo per poter fornire RemoteViews al selettore di widget.
Le app possono utilizzare setWidgetPreview in AppWidgetManager. Per prevenire abusi e mitigare i problemi di integrità del sistema, setWidgetPreview è un'API con limitazione di frequenza.
Il limite predefinito è di circa due chiamate all'ora.
Non è previsto un callback dal sistema per fornire le anteprime, quindi la tua app deve decidere quando chiamare setWidgetPreviews. La strategia di aggiornamento dipende dal caso d'uso del widget:
- Se il widget contiene informazioni statiche o è un'azione rapida, imposta l'anteprima al primo avvio dell'app.
- Puoi impostare l'anteprima una volta che l'app ha i dati, ad esempio dopo l'accesso di un utente o la configurazione iniziale.
- Puoi configurare un'attività periodica per aggiornare le anteprime con la frequenza che preferisci.
L'esempio seguente carica una risorsa di layout del widget XML e la imposta come anteprima. Perché setWidgetPreview venga visualizzato come metodo in questo snippet, è necessario impostare compileSdk su 35 o versioni successive.
AppWidgetManager.getInstance(appContext).setWidgetPreview(
ComponentName(
appContext,
ExampleAppWidgetReceiver::class.java
),
AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
RemoteViews("com.example", R.layout.widget_preview)
)
Aggiungere anteprime dei widget scalabili
A partire da Android 12, l'anteprima del widget visualizzata nel selettore di widget è scalabile. Devi fornirla come layout XML impostato sulla dimensione predefinita del widget. In precedenza, l'anteprima del widget era una risorsa disegnabile statica, il che in alcuni casi portava a anteprime che non riflettevano con precisione l'aspetto dei widget quando venivano aggiunti alla schermata Home.
Per implementare le anteprime dei widget scalabili, utilizza l'
previewLayout
attributo dell'elemento appwidget-provider per fornire un layout XML:
<appwidget-provider
android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Ti consigliamo di utilizzare lo stesso layout del widget effettivo, con valori predefiniti o di test realistici. La maggior parte delle app utilizza lo stesso previewLayout e initialLayout. Per
indicazioni sulla creazione di layout di anteprima accurati, consulta
Creare anteprime accurate che includono elementi dinamici.
Ti consigliamo di specificare sia gli attributi previewLayout sia previewImage, in modo che la tua app possa tornare a utilizzare previewImage se il dispositivo dell'utente non supporta previewLayout. L'attributo previewLayout ha la precedenza sull'attributo previewImage.
Aggiungere anteprime dei widget statiche per la compatibilità con le versioni precedenti
Per consentire ai selettori di widget su Android 11 (livello API 30) o versioni precedenti di mostrare le anteprime del tuo
widget o come fallback per le anteprime scalabili, specifica l'previewImage
attributo.
Se modifichi l'aspetto del widget, aggiorna l'immagine di anteprima.
Questo attributo viene utilizzato anche come fallback per le anteprime generate se non ne hai impostata una utilizzando setWidgetPreview.
Creare anteprime accurate che includono elementi dinamici
Questa sezione spiega l'approccio consigliato per visualizzare più elementi nell'anteprima di un widget con una visualizzazione di raccolta, ovvero un widget che utilizza un ListView, GridView o StackView. Questo vale per le anteprime dei widget scalabili, non per le anteprime generate.
Se il widget utilizza una di queste visualizzazioni, la creazione di un'anteprima scalabile fornendo il layout del widget effettivo direttamente in previewLayout può peggiorare l'esperienza quando l'anteprima del widget non mostra elementi. Questo accade perché i dati della visualizzazione di raccolta vengono impostati dinamicamente in fase di runtime e l'aspetto è simile all'immagine mostrata nella figura 1.
Per fare in modo che le anteprime dei widget con visualizzazioni di raccolta vengano visualizzate correttamente nel selettore di widget, ti consigliamo di mantenere un file di layout separato designato solo per l'anteprima. Questo file di layout separato deve includere:
- Il layout del widget effettivo.
- Una visualizzazione di raccolta segnaposto con elementi fittizi. Ad esempio, puoi simulare un
ListViewfornendo unLinearLayoutsegnaposto con diverse voci di elenco fittizie.
Per illustrare un esempio per un ListView, inizia con un file di layout separato:
// res/layout/widget_preview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_background"
android:orientation="vertical">
// Include the actual widget layout that contains ListView.
<include
layout="@layout/widget_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// The number of fake items you include depends on the values you provide
// for minHeight or targetCellHeight in the AppWidgetProviderInfo
// definition.
<TextView android:text="@string/fake_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
<TextView android:text="@string/fake_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
</LinearLayout>
Specifica il file di layout di anteprima quando fornisci l'attributo previewLayout dei metadati AppWidgetProviderInfo. Devi comunque specificare il layout del widget effettivo per l'attributo initialLayout e utilizzare il layout del widget effettivo quando costruisci un RemoteViews in fase di runtime.
<appwidget-provider
previewLayout="@layout/widget_preview"
initialLayout="@layout/widget_view" />
Voci di elenco complesse
L'esempio nella sezione precedente fornisce voci di elenco fittizie, perché le voci di elenco sono TextView oggetti. Può essere più complesso fornire elementi fittizi se gli elementi sono layout complessi.
Considera una voce di elenco definita in widget_list_item.xml e composta da due oggetti TextView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_title" />
<TextView android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_content" />
</LinearLayout>
Per fornire voci di elenco fittizie, puoi includere il layout più volte, ma in questo modo ogni voce di elenco sarà identica. Per fornire voci di elenco uniche:
Crea un insieme di attributi per i valori di testo:
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>Utilizza questi attributi per impostare il testo:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetTitle" /> <TextView android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetContent" /> </LinearLayout>Crea tutti gli stili necessari per l'anteprima. Ridefinisci i valori in ogni stile:
<resources> <style name="Theme.Widget.ListItem"> <item name="widgetTitle"></item> <item name="widgetContent"></item> </style> <style name="Theme.Widget.ListItem.Preview1"> <item name="widgetTitle">Fake Title 1</item> <item name="widgetContent">Fake content 1</item> </style> <style name="Theme.Widget.ListItem.Preview2"> <item name="widgetTitle">Fake title 2</item> <item name="widgetContent">Fake content 2</item> </style> </resources>Applica gli stili agli elementi fittizi nel layout di anteprima:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" ...> <include layout="@layout/widget_view" ... /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview1" /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview2" /> </LinearLayout>