Creare un widget semplice

I widget sono visualizzazioni in miniatura delle app che puoi incorporare in altre come la schermata Home, e ricevono aggiornamenti periodici. Questi di visualizzazione sono chiamate widget nell'interfaccia utente e puoi pubblicare Uno con un fornitore di widget per app (o fornitore di widget). Un componente dell'app che contiene altri widget è chiamato host del widget dell'app (o host widget). Figura 1 mostra un widget musicale di esempio:

Esempio di widget per la musica
Figura 1. Esempio di widget musicali.

Questo documento descrive come pubblicare un widget utilizzando un fornitore di widget. Per dettagli sulla creazione di AppWidgetHost widget di app host, consulta Creare un host per i widget.

Per informazioni su come progettare il widget, consulta Panoramica dei widget app.

Componenti widget

Per creare un widget, sono necessari i seguenti componenti di base:

Oggetto AppWidgetProviderInfo
Descrive i metadati per un widget, ad esempio il layout, l'aggiornamento frequenza e classe AppWidgetProvider. AppWidgetProviderInfo è definito in XML, come descritti in questo documento.
Corso AppWidgetProvider
Definisce i metodi di base che ti consentono di interfacciarti in modo programmatico con il widget. Grazie a questo strumento, ricevi annunci quando il widget viene aggiornato, attivato, disattivato o eliminato. dichiari AppWidgetProvider nel manifest e poi implementalo, descritti in questo documento.
Visualizza layout
definisce il layout iniziale per il widget. Il layout è definito in XML, come descritto in questo documento.

La figura 2 mostra come questi componenti si inseriscono nell'elaborazione complessiva del widget dell'app flusso di lavoro.

Flusso di elaborazione dei widget dell'app
Figura 2. Flusso di elaborazione dei widget dell'app.
di Gemini Advanced.

Se il widget richiede la configurazione utente, implementa la configurazione del widget dell'app attività. Questa attività consente agli utenti di modificare le impostazioni del widget, ad esempio il fuso orario per un widget orologio.

Consigliamo inoltre i seguenti miglioramenti: layout flessibile dei widget, miglioramenti vari, widget avanzati, widget di raccolta e creazione di un widget host.

Dichiara il file XML AppWidgetProviderInfo

L'oggetto AppWidgetProviderInfo definisce le qualità essenziali di un widget. Definisci l'oggetto AppWidgetProviderInfo in un file di risorse XML utilizzando un singolo <appwidget-provider> e salvalo nella cartella res/xml/ del progetto.

Ciò è mostrato nell'esempio seguente:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:targetCellWidth="1"
    android:targetCellHeight="1"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="120dp"
    android:updatePeriodMillis="86400000"
    android:description="@string/example_appwidget_description"
    android:previewLayout="@layout/example_appwidget_preview"
    android:initialLayout="@layout/example_loading_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

Attributi di dimensionamento dei widget

La schermata Home predefinita posiziona i widget all'interno della finestra in base a una griglia di celle che hanno un'altezza e una larghezza definite. Nella maggior parte delle schermate Home, i widget sono attivi di dimensioni che sono multipli interi delle celle della griglia, ad esempio due celle orizzontalmente, tre celle in verticale.

Gli attributi di dimensionamento del widget consentono di specificare una dimensione predefinita per il widget e limiti inferiori e superiori alle dimensioni del widget. In questo contesto, la dimensione predefinita di un widget è quella assunta dal widget alla prima aggiunto alla schermata Home.

La seguente tabella descrive gli attributi <appwidget-provider> relativi al dimensionamento dei widget:

Attributi e descrizione
targetCellWidth e targetCellHeight (Android 12), minWidth e minHeight
  • A partire da Android 12, targetCellWidth e targetCellHeight specificano la dimensione predefinita del widget in termini di griglia celle. Questi attributi vengono ignorati in Android 11 e inferiore ed può essere ignorato se la schermata Home non supportano un layout basato su griglia.
  • Le minWidth e Gli attributi minHeight specificano la dimensione predefinita del widget in dp. Se i valori della larghezza o dell'altezza minima di un widget non corrispondono le dimensioni delle celle, i valori vengono arrotondati per eccesso dimensione della cella più vicina.
di Gemini Advanced. Ti consigliamo di specificare entrambi gli insiemi attributi: targetCellWidth e targetCellHeight, minWidth e minHeight, in modo che la tua app possa utilizzare minWidth e minHeight se il dispositivo dell'utente non supporta targetCellWidth e targetCellHeight. Se supportata, Attributi targetCellWidth e targetCellHeight hanno la precedenza su minWidth e minHeight attributi.
minResizeWidth e minResizeHeight Specifica la dimensione minima assoluta del widget. Questi valori specificano le dimensioni con le quali il widget risulta illeggibile o comunque inutilizzabile. Utilizzo questi attributi consentono all'utente di ridimensionare il widget a una dimensione inferiore rispetto alle dimensioni predefinite del widget. L'attributo minResizeWidth è ignorato se è maggiore di minWidth o se orizzontale il ridimensionamento non è abilitato. Consulta resizeMode Analogamente, L'attributo minResizeHeight viene ignorato se è maggiore di minHeight o se il ridimensionamento verticale non è abilitato.
maxResizeWidth e maxResizeHeight Specifica la dimensione massima consigliata del widget. Se i valori non sono multiplo delle dimensioni delle celle della griglia, vengono arrotondati al valore più vicino dimensioni della cella. L'attributo maxResizeWidth viene ignorato se è minore di minWidth o se il ridimensionamento orizzontale non in un bucket con il controllo delle versioni attivo. Vedi resizeMode. Analogamente, l'attributo maxResizeHeight viene ignorato se è maggiore di minHeight o se il ridimensionamento verticale non è abilitato. Introdotta in Android 12.
resizeMode Specifica le regole in base alle quali un widget può essere ridimensionato. Puoi utilizzare questo per rendere i widget della schermata Home ridimensionabili orizzontalmente, verticalmente o su entrambi gli assi. Gli utenti toccano e tieni premuto un widget per visualizzarne i punti di manipolazione di ridimensionamento quindi trascina i punti di manipolazione orizzontali o verticali per modificarne le dimensioni griglia di layout. I valori per l'attributo resizeMode includono horizontal, vertical e none. A dichiarare un widget ridimensionabile orizzontalmente e verticalmente, utilizza horizontal|vertical.

Esempio

Per illustrare come gli attributi nella tabella precedente influiscono sulle dimensioni del widget, presupponi le seguenti specifiche:

  • Una cella della griglia ha una larghezza di 30 dp e un'altezza di 50 dp.
  • Vengono fornite le seguenti specifiche degli attributi:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="80dp"
    android:targetCellWidth="2"
    android:targetCellHeight="2"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:maxResizeWidth="120dp"
    android:maxResizeHeight="120dp"
    android:resizeMode="horizontal|vertical" />

A partire da Android 12:

Utilizza gli attributi targetCellWidth e targetCellHeight come predefiniti dimensione del widget.

Per impostazione predefinita, le dimensioni del widget sono 2 x 2. Il widget può essere ridimensionato a 2 x 1 oppure fino a 4 x 3.

Android 11 e versioni precedenti:

Utilizza gli attributi minWidth e minHeight per calcolare la dimensione predefinita di nel widget.

Larghezza predefinita = Math.ceil(80 / 30) = 3

Altezza predefinita = Math.ceil(80 / 50) = 2

Le dimensioni del widget sono 3 x 2 per impostazione predefinita. Il widget può essere ridimensionato a 2 x 1 oppure fino a schermo intero.

Attributi aggiuntivi del widget

La seguente tabella descrive gli attributi <appwidget-provider> relativi a qualità diverse dal dimensionamento dei widget.

Attributi e descrizione
updatePeriodMillis Definisce la frequenza con cui il framework del widget richiede un aggiornamento all'oggetto AppWidgetProvider chiamando il onUpdate() di callback di Google. Non è garantito che l'aggiornamento effettivo avvenga esattamente il giorno tempo con questo valore e consigliamo di eseguire l'aggiornamento con la frequenza non più di una volta all'ora, per risparmiare batteria. Per l'elenco completo delle considerazioni sulla scelta di un periodo di aggiornamento appropriato, vedi Ottimizzazioni per l'aggiornamento del widget .
initialLayout Punta alla risorsa di layout che definisce il layout del widget.
configure Definisce l'attività che viene avviata quando l'utente aggiunge il widget, per configurare le proprietà del widget. Consulta Consentire agli utenti di configurare i widget. A partire da Android 12, la tua app può saltare il passaggio iniziale configurazione. Consulta la sezione Utilizzare il configurazione predefinita del widget per maggiori dettagli.
description Specifica la descrizione che il selettore widget deve mostrare per il tuo widget. Introdotta in Android 12.
previewLayout (Android 12) e previewImage (Android 11 e versioni precedenti)
  • A partire da Android 12, L'attributo previewLayout specifica un'anteprima scalabile, che che fornisci come layout XML impostato sulle dimensioni predefinite del widget. L'ideale è il file XML di layout specificato perché questo attributo è lo stesso XML di layout del widget effettivo con valori predefiniti realistici.
  • In Android 11 o versioni precedenti, previewImage specifica un'anteprima dell'aspetto del widget dopo configurata, che l'utente vede quando seleziona il widget dell'app. In caso contrario fornita, l'utente vede invece l'icona in Avvio applicazioni dell'app. Questo corrisponde all'attributo android:previewImage in l'elemento <receiver> nel AndroidManifest.xml file.
di Gemini Advanced. Nota: consigliamo di specificare sia previewImage e previewLayout per consentire alla tua app di tornare all'utilizzo di previewImage se il dispositivo dell'utente non supporta previewLayout. Per ulteriori dettagli, vedi Compatibilità con le versioni precedenti anteprime del widget.
autoAdvanceViewId Specifica l'ID vista della vista secondaria del widget avanzata automaticamente da l'host del widget.
widgetCategory Dichiara se il widget può essere visualizzato nella schermata Home (home_screen), la schermata di blocco (keyguard) o entrambi. Per Android 5.0 e versioni successive, è valido soltanto home_screen.
widgetFeatures Dichiara le funzionalità supportate dal widget. Ad esempio, se vuoi il widget di utilizzare la configurazione predefinita quando un utente lo aggiunge, sia il configuration_optional e reconfigurable e i flag facoltativi. In questo modo viene ignorato l'avvio dell'attività di configurazione dopo che l'utente aggiunge il widget. L'utente può comunque riconfigura il widget in seguito.

Utilizzo della classe AppWidgetProvider per gestire le trasmissioni del widget

La classe AppWidgetProvider gestisce la trasmissione del widget e lo aggiorna in risposta agli eventi del ciclo di vita dei widget. Le seguenti sezioni descrivono come dichiarare AppWidgetProvider nel file manifest e implementarlo.

Dichiara un widget nel manifest

Innanzitutto, dichiara la classe AppWidgetProvider nel file AndroidManifest.xml della tua app come mostrato nell'esempio seguente:

<receiver android:name="ExampleAppWidgetProvider"
                 android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>

L'elemento <receiver> richiede l'attributo android:name, che specifica AppWidgetProvider utilizzato dal widget. Il componente non deve essere esportato a meno che non sia necessario trasmettere al tuo AppWidgetProvider un processo separato, in genere non è così.

L'elemento <intent-filter> deve includere un elemento <action> con il android:name. Questo attributo specifica che l'elemento AppWidgetProvider accetta il ACTION_APPWIDGET_UPDATE la trasmissione. Questa è l'unica trasmissione che devi dichiarare esplicitamente. La AppWidgetManager invia automaticamente tutte le altre trasmissioni del widget a AppWidgetProvider come necessaria.

L'elemento <meta-data> specifica la risorsa AppWidgetProviderInfo e richiede i seguenti attributi:

  • android:name: specifica il nome dei metadati. Utilizza le funzionalità di android.appwidget.provider per identificare i dati come descrittore AppWidgetProviderInfo.
  • android:resource: specifica la risorsa AppWidgetProviderInfo in ogni località.

Implementare la classe AppWidgetProvider

Il corso AppWidgetProvider si estende BroadcastReceiver come per gestire le trasmissioni del widget. Riceve solo l'evento annunci rilevanti per il widget, ad esempio quando quest'ultimo viene aggiornato, eliminati, attivati e disattivati. Quando si verificano questi eventi di trasmissione, viene: I metodi AppWidgetProvider vengono chiamati:

onUpdate()
La chiamata viene chiamata ad aggiornare il widget a intervalli definiti dal updatePeriodMillis in AppWidgetProviderInfo. Consulta la tabella che descrivono altri attributi del widget in questa pagina per ulteriori informazioni.
di Gemini Advanced.
Questo metodo viene chiamato anche quando l'utente aggiunge il widget, quindi esegue configurazione essenziale, come la definizione di gestori di eventi View oggetti o job in cui caricare i dati in fase di avvio nel widget. Tuttavia, se dichiari un'attività di configurazione senza il flag configuration_optional, questo metodo non viene chiamato quando l'utente aggiunge il widget, ma viene richiamato per gli aggiornamenti successivi. È la responsabilità dell'attività di configurazione di eseguire il primo aggiornamento configurazione completata. Per ulteriori informazioni, vedi Consentire agli utenti di configurare i widget delle app.
di Gemini Advanced.
Il callback più importante è onUpdate(). Vedi Gestire gli eventi con onUpdate() corso in questa pagina per saperne di più.
onAppWidgetOptionsChanged()

Viene chiamato quando il widget viene posizionato per la prima volta e ogni volta che viene viene ridimensionato. Utilizza questo callback per mostrare o nascondere i contenuti in base alle dimensioni del widget intervalli di tempo. Visualizza le intervalli di dimensioni e, a partire da Android 12, l'elenco delle possibili dimensioni che un'istanza di widget può assumere, chiamando getAppWidgetOptions(), che restituisce un elemento Bundle che include seguenti:

onDeleted(Context, int[])

Questo viene chiamato ogni volta che un widget viene eliminato dall'host del widget.

onEnabled(Context)

Questo viene chiamato quando un'istanza del widget viene creata per la prima volta. Ad esempio, se l'utente aggiunge due istanze del widget, questa viene chiamata per la prima volta. Se devi aprire un nuovo database o eseguire un'altra configurazione deve verificarsi una sola volta per tutte le istanze del widget, questo è un buon posto fallo.

onDisabled(Context)

Questo viene chiamato quando l'ultima istanza del widget viene eliminata dalla dell'host del widget. Da qui puoi sistemare il lavoro svolto in onEnabled(Context), ad esempio eliminando un database temporaneo.

onReceive(Context, Intent)

Viene richiesto per ogni trasmissione e prima di ciascuno dei callback precedenti di machine learning. In genere non è necessario implementare questo metodo, perché il metodo predefinito L'implementazione di AppWidgetProvider filtra tutti gli annunci e le chiamate del widget metodi precedenti, a seconda dei casi.

Devi dichiarare l'implementazione della classe AppWidgetProvider come una trasmissione ricevitore utilizzando l'elemento <receiver> in AndroidManifest. Consulta la sezione Dichiarare nel file manifest di questa pagina per ulteriori informazioni.

Gestire gli eventi con la classe onUpdate()

Il callback più importante per AppWidgetProvider è onUpdate(), perché è chiamato quando ciascun widget viene aggiunto a un host, a meno che non utilizzi una attività senza il flag configuration_optional. Se il widget accetta eventi di interazione dell'utente, quindi registra i gestori di eventi in questo callback. Se il widget non crea file o database temporanei e non esegue altre operazioni che richiede la pulizia, onUpdate() potrebbe essere l'unico metodo di callback che devono definire.

Ad esempio, se vuoi un widget con un pulsante che avvia un'attività quando toccato, puoi utilizzare la seguente implementazione di AppWidgetProvider:

Kotlin

class ExampleAppWidgetProvider : AppWidgetProvider() {

    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray
    ) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        appWidgetIds.forEach { appWidgetId ->
            // Create an Intent to launch ExampleActivity.
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                    /* context = */ context,
                    /* requestCode = */  0,
                    /* intent = */ Intent(context, ExampleActivity::class.java),
                    /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            val views: RemoteViews = RemoteViews(
                    context.packageName,
                    R.layout.appwidget_provider_layout
            ).apply {
                setOnClickPendingIntent(R.id.button, pendingIntent)
            }

            // Tell the AppWidgetManager to perform an update on the current
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

Java

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        for (int i=0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                /* context = */ context,
                /* requestCode = */ 0,
                /* intent = */ intent,
                /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
            );

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current app
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

Questo AppWidgetProvider definisce solo il metodo onUpdate(), utilizzandolo per crea una PendingIntent che avvia un Activity e lo collega al widget utilizzando setOnClickPendingIntent(int, PendingIntent). Include un loop che si ripete per ogni voce in appWidgetIds, che è un array di ID che identificano ciascun widget creato questo fornitore. Se l'utente crea più di un'istanza del widget, vengono aggiornati tutti contemporaneamente. Tuttavia, solo una pianificazione updatePeriodMillis viene gestito per tutte le istanze del widget. Ad esempio, se la pianificazione dell'aggiornamento viene definito ogni due ore e viene aggiunta una seconda istanza del widget un'ora dopo la prima, vengono aggiornate entrambe nel periodo definito il primo e il secondo periodo di aggiornamento viene ignorato. Entrambi si aggiornano ogni due ore, non ogni ora.

Consulta le ExampleAppWidgetProvider.java esempio di classe per ulteriori dettagli.

Ricevi intent di trasmissione del widget

AppWidgetProvider è un corso di convenienza. Se vuoi ricevere il widget trasmette direttamente, puoi implementare il tuo BroadcastReceiver o eseguire l'override il Chiamata di onReceive(Context,Intent). Gli intent che ti interessano sono seguenti:

Creare il layout del widget

Devi definire un layout iniziale per il widget in XML e salvarlo nel directory res/layout/ del progetto. Fai riferimento alla sezione Progettazione linee guida.

Creare il layout del widget è semplice se conosci layout. Tuttavia, tieni presente che il widget layout si basano su RemoteViews, che non supporta tutti i tipi di widget di layout o di visualizzazione. Non puoi usare le impostazioni personalizzate viste o sottoclassi delle viste supportate da RemoteViews.

RemoteViews supporta anche ViewStub, che è un View invisibile a dimensione zero che puoi utilizzare per gonfiare lentamente il layout delle risorse in fase di runtime.

Supporto per il comportamento stateful

Android 12 aggiunge il supporto per il comportamento stateful tramite: componenti esistenti:

Il widget è ancora stateless. L'app deve archiviare lo stato e registrarsi eventi di modifica dello stato.

Esempio di widget della lista della spesa che mostra il comportamento stateful
Figura 3. Esempio di comportamento stateful.
di Gemini Advanced.

Il codice di esempio riportato di seguito mostra come implementare questi componenti.

Kotlin

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
        R.id.my_checkbox,
        RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Java

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true);

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2);

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));

Fornisci due layout: uno per dispositivi di targeting con Android 12 o più elevata in res/layout-v31 e l'altro targeting precedente Android 11 o versioni precedenti nella cartella res/layout predefinita.

Implementa gli angoli arrotondati

Android 12 introduce i seguenti parametri di sistema per impostare raggi degli angoli arrotondati del widget:

  • system_app_widget_background_radius: il raggio d'angolo dello sfondo del widget, che non è mai più grande di 28 dp.

  • system_app_widget_inner_radius: il raggio degli angoli di qualsiasi vista all'interno del widget. Sono esattamente 8 dp. inferiore al raggio dello sfondo, per allinearsi bene quando si utilizza un raggio di 8 dp spaziatura interna.

L'esempio seguente mostra un widget che utilizza system_app_widget_background_radius per l'angolo del widget e system_app_widget_inner_radius per le visualizzazioni all'interno del widget.

Widget che mostra i raggi dello sfondo del widget e le visualizzazioni all&#39;interno del widget
Figura 4. Angoli arrotondati.

1 Angolo del widget.

2 Angolo di una visualizzazione all'interno del widget.

Considerazioni importanti per gli angoli arrotondati

  • Le app di avvio applicazioni e i produttori di dispositivi di terze parti possono sostituire le system_app_widget_background_radius deve essere inferiore a 28 dp. Il parametro system_app_widget_inner_radius è sempre 8 dp inferiore a il valore di system_app_widget_background_radius.
  • Se il widget non utilizza @android:id/background o non definisce uno sfondo che ritaglia i contenuti in base al contorno, con android:clipToOutline impostata su true: Avvio app identifica automaticamente lo sfondo e ritaglia il widget utilizzando un rettangolo con angoli arrotondati di massimo 16 dp. Vedi Assicurarsi che il widget sia compatibile con Android 12.

Per la compatibilità dei widget con le versioni precedenti di Android, ti consigliamo definire attributi personalizzati e utilizzare un tema personalizzato per sostituirli Android 12, come mostrato nei seguenti file XML di esempio:

/values/attrs.xml

<resources>
  <attr name="backgroundRadius" format="dimension" />
</resources>

/values/styles.xml

<resources>
  <style name="MyWidgetTheme">
    <item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
  </style>
</resources>

/values-31/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
    <item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
  </style>
</resources>

/drawable/my_widget_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners android:radius="?attr/backgroundRadius" />
  ...
</shape>

/layout/my_widget_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  android:background="@drawable/my_widget_background" />