Para melhorar a experiência do seletor de widgets do app, forneça uma visualização gerada do widget em dispositivos com o Android 15 e versões mais recentes, uma visualização escalonada do widget (especificando um previewLayout) para dispositivos com o Android 12 a 14 e uma previewImage para versões anteriores.
As visualizações geradas de widgets permitem criar visualizações dinâmicas e personalizadas para seus widgets que refletem com precisão como eles vão aparecer na tela inicial de um usuário. No Android 15 e versões mais recentes, elas são fornecidas por uma API push, o que significa que o app fornece a visualização a qualquer momento durante o ciclo de vida, sem receber uma solicitação explícita do host do widget.
Para mais informações, consulte Enriquecer seu app com atualizações em tempo real e widgets no YouTube.
Adicionar visualizações geradas
Para mostrar visualizações geradas de widgets em dispositivos com o Android 15 ou versões mais recentes, primeiro defina o
compileSdk valor como 35 ou mais recente no arquivo build.gradle do módulo para poder fornecer RemoteViews ao seletor de widgets.
Os apps podem usar setWidgetPreview em AppWidgetManager. Para evitar abusos e mitigar problemas de integridade do sistema, setWidgetPreview é uma API com limitação de taxa.
O limite padrão é de aproximadamente duas chamadas por hora.
Não há um callback do sistema para fornecer visualizações. Portanto, o app precisa decidir quando chamar setWidgetPreviews. A estratégia de atualização depende do caso de uso do widget:
- Se o widget tiver informações estáticas ou for uma ação rápida, defina a visualização quando o app for iniciado pela primeira vez.
- Você pode definir a visualização assim que o app tiver dados, por exemplo, após o login do usuário ou a configuração inicial.
- É possível configurar uma tarefa periódica para atualizar as visualizações em uma cadência escolhida.
O exemplo a seguir carrega um recurso de layout de widget XML e o define como a visualização. Uma configuração de build do compileSdk 35 ou mais recente é necessária para que setWidgetPreview apareça como um método nesse snippet.
AppWidgetManager.getInstance(appContext).setWidgetPreview(
ComponentName(
appContext,
ExampleAppWidgetReceiver::class.java
),
AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
RemoteViews("com.example", R.layout.widget_preview)
)
Adicionar visualizações de widgets escalonáveis
A partir do Android 12, a visualização do widget exibida no seletor de widgets é escalonável. Ela é fornecida como um layout XML definido para o tamanho padrão do widget. Anteriormente, a visualização do widget era um recurso drawable estático, em alguns casos, a visualização não refletia corretamente os widgets quando eles eram adicionados à tela inicial.
Para implementar visualizações de widgets escalonáveis, use o
previewLayout
atributo do appwidget-provider elemento para fornecer um layout XML:
<appwidget-provider
android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Recomendamos usar o mesmo layout do widget real, com valores padrão ou de teste realistas. A maioria dos apps usa o mesmo previewLayout e initialLayout. Para
orientações sobre como criar layouts de visualização precisos, consulte
Criar visualizações precisas que incluem itens dinâmicos.
Recomendamos especificar os atributos previewLayout e previewImage, para que o app possa voltar a usar previewImage se o dispositivo do usuário não for compatível com previewLayout. O atributo previewLayout tem precedência sobre o atributo previewImage.
Adicionar visualizações de widgets estáticos para compatibilidade com versões anteriores
Para permitir que os seletores de widgets no Android 11 (nível 30 da API) ou versões anteriores mostrem visualizações do seu widget ou como um substituto para visualizações escalonáveis, especifique o previewImage atributo.
Se você mudar a aparência do widget, atualize a imagem de visualização.
Esse atributo também é usado como um substituto para visualizações geradas se você não tiver definido uma usando setWidgetPreview.
Criar visualizações precisas que incluem itens dinâmicos
Esta seção explica a abordagem recomendada para mostrar vários itens em
uma visualização de widget para um widget com uma visualização de coleção, ou seja, um
widget que usa uma ListView, GridView ou StackView. Isso se aplica a visualizações de widgets escalonáveis, não a visualizações geradas.
Se o widget usar uma dessas visualizações, a criação de uma visualização escalonável fornecendo o layout real do widget diretamente em previewLayout poderá degradar a experiência quando a visualização do widget não mostrar itens. Isso ocorre porque os dados da visualização de coleção são definidos dinamicamente no tempo de execução e são semelhantes à imagem mostrada na Figura 1.
Para que as visualizações de widgets com visualizações de coleção sejam exibidas corretamente no seletor de widgets, recomendamos manter um arquivo de layout separado designado apenas para a visualização. Esse arquivo de layout separado precisa incluir o seguinte:
- O layout real do widget.
- Uma visualização de coleção de marcador de posição com itens falsos. Por exemplo, é possível imitar uma
ListViewfornecendo umLinearLayoutde marcador de posição com vários itens de lista falsos.
Para ilustrar um exemplo de ListView, comece com um arquivo de layout separado:
// 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>
Especifique o arquivo de layout de visualização ao fornecer o atributo previewLayout dos metadados AppWidgetProviderInfo. Você ainda especifica o layout real do widget para o atributo initialLayout e usa o layout real do widget ao construir um RemoteViews no tempo de execução.
<appwidget-provider
previewLayout="@layout/widget_preview"
initialLayout="@layout/widget_view" />
Itens de lista complexos
O exemplo na seção anterior fornece itens de lista falsos, porque os itens
de lista são TextView objetos. Pode ser mais complexo fornecer itens falsos se eles forem layouts complexos.
Considere um item de lista definido em widget_list_item.xml e que consiste em dois objetos 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>
Para fornecer itens de lista falsos, é possível incluir o layout várias vezes, mas isso faz com que cada item de lista seja idêntico. Para fornecer itens de lista exclusivos, siga estas etapas:
Crie um conjunto de atributos para os valores de texto:
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>Use esses atributos para definir o texto:
<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>Crie quantos estilos forem necessários para a visualização. Redefina os valores em cada estilo:
<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>Aplique os estilos nos itens falsos no layout de visualização:
<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>