Чтобы улучшить выбор виджетов в приложении, добавьте сгенерированный предпросмотр виджета на устройствах с Android 15 и более поздних версий, масштабированный предпросмотр виджета (с помощью previewLayout) на устройствах с Android 12–14 и previewImage на устройствах с более ранними версиями Android.
Предварительные версии виджетов, созданные с помощью ИИ, позволяют создавать динамические персонализированные виджеты, которые точно отражают то, как они будут выглядеть на главном экране пользователя. В Android 15 и более поздних версий они предоставляются через API push-уведомлений. Это означает, что ваше приложение предоставляет предварительный просмотр в любой момент своего жизненного цикла, не получая явного запроса от хоста виджета.
Подробнее о том, как добавить в приложение виджеты и обновления в реальном времени…
Как добавить сгенерированные изображения для предпросмотра
Чтобы на устройстве с Android 15 или более поздней версией ОС показывались сгенерированные предварительные версии виджетов, сначала задайте для параметра compileSdk значение 35 или более позднее в файле модуля build.gradle, чтобы иметь возможность передавать RemoteViews в средство выбора виджетов.
Приложения могут использовать setWidgetPreview в AppWidgetManager. Чтобы предотвратить злоупотребления и снизить нагрузку на систему, setWidgetPreview – это API с ограничением частоты запросов.
По умолчанию можно совершать примерно два звонка в час.
Система не предоставляет обратный вызов для предпросмотра, поэтому ваше приложение должно самостоятельно определять, когда вызывать метод setWidgetPreviews. Стратегия обновления зависит от того, как используется виджет:
- Если виджет содержит статическую информацию или позволяет выполнять быстрые действия, задайте предварительный просмотр при первом запуске приложения.
- Вы можете настроить предварительный просмотр после того, как в приложении появятся данные, например после входа пользователя в аккаунт или первоначальной настройки.
- Вы можете настроить периодическую задачу для обновления предварительного просмотра с выбранной частотой.
В следующем примере загружается ресурс макета виджета XML и задается в качестве предварительного просмотра. Чтобы метод setWidgetPreview отображался в этом фрагменте кода, для параметра compileSdk в файле сборки должно быть задано значение 35 или более поздней версии.
AppWidgetManager.getInstance(appContext).setWidgetPreview(
ComponentName(
appContext,
ExampleAppWidgetReceiver::class.java
),
AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
RemoteViews("com.example", R.layout.widget_preview)
)
Как добавить масштабируемые предпросмотры виджетов
В Android 12 и более поздних версиях предпросмотр виджета, который показывается в окне выбора виджетов, можно масштабировать. Вы предоставляете его в виде макета XML, заданного для размера виджета по умолчанию. Раньше в качестве предпросмотра виджета использовался статический ресурс drawable, из-за чего в некоторых случаях предпросмотр неточно отражал то, как виджет будет выглядеть после добавления на главный экран.
Чтобы реализовать масштабируемые предварительные просмотры виджетов, используйте атрибут previewLayout элемента appwidget-provider, чтобы предоставить макет XML:
<appwidget-provider
android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Рекомендуем использовать тот же макет, что и в виджете, с реалистичными значениями по умолчанию или тестовыми значениями. В большинстве приложений используются одни и те же значения previewLayout и initialLayout. Инструкции по созданию точных макетов для предпросмотра приведены в статье Как создавать точные макеты для предпросмотра с динамическими элементами.
Мы рекомендуем указывать оба атрибута: previewLayout и previewImage. В этом случае, если устройство пользователя не поддерживает previewLayout, приложение сможет использовать previewImage. Атрибут "previewLayout" имеет приоритет над атрибутом "previewImage".
Добавьте статические изображения виджетов для обратной совместимости
Чтобы в окне выбора виджетов на устройствах с Android 11 (уровень API 30) или более ранних версий показывались предварительные изображения виджетов, а также в качестве резервного варианта для масштабируемых изображений, укажите атрибут previewImage.
Если вы измените внешний вид виджета, обновите изображение для предпросмотра.
Этот атрибут также используется в качестве резервного для сгенерированных фрагментов, если вы не задали его с помощью атрибута setWidgetPreview.
Создавайте точные предпросмотры с динамическими элементами
В этом разделе рассказывается, как лучше всего показывать несколько объектов в предварительном просмотре виджета с представлением коллекции, то есть виджета, в котором используется ListView, GridView или StackView. Это относится к предварительным просмотрам масштабируемых виджетов, а не к сгенерированным предварительным просмотрам.
Если в виджете используется один из этих представлений, создание масштабируемого предварительного просмотра путем предоставления фактической разметки виджета непосредственно в previewLayout может ухудшить качество работы, когда в предварительном просмотре виджета не отображаются элементы. Это происходит потому, что данные представления коллекции задаются динамически во время выполнения и выглядят так же, как на изображении 1.
Чтобы предварительный просмотр виджетов с представлениями коллекций корректно отображался в окне выбора виджетов, мы рекомендуем создать отдельный файл макета, предназначенный только для предварительного просмотра. Этот отдельный файл макета должен содержать следующие элементы:
- Макет виджета.
- Представление коллекции с плейсхолдерами и фиктивными элементами. Например, вы можете имитировать
ListView, предоставив заполнительLinearLayoutс несколькими фиктивными элементами списка.
Чтобы показать пример использования атрибута ListView, начнем с отдельного файла макета:
// 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>
Укажите файл макета предпросмотра, когда будете добавлять атрибут previewLayout метаданных AppWidgetProviderInfo. При этом вы по-прежнему указываете фактическую разметку виджета в атрибуте "разметка виджета" initialLayout и используете ее при создании атрибута "разметка виджета" RemoteViews во время выполнения.
<appwidget-provider
previewLayout="@layout/widget_preview"
initialLayout="@layout/widget_view" />
Сложные элементы списка
В примере из предыдущего раздела приведены фиктивные элементы списка, поскольку элементы списка являются объектами TextView. Если макеты сложные, то поддельные объекты могут быть сложнее.
Предположим, что элемент списка определен в widget_list_item.xml и состоит из двух объектов 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>
Чтобы добавить в список фиктивные элементы, можно несколько раз включить макет, но в этом случае все элементы будут одинаковыми. Чтобы создать уникальные элементы списка, выполните следующие действия:
Создайте набор атрибутов для текстовых значений:
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>Чтобы задать текст, используйте следующие атрибуты:
<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>Создайте столько стилей, сколько нужно для предварительного просмотра. Задайте новые значения для каждого стиля:
<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>Примените стили к фиктивным объектам в макете предварительного просмотра:
<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>