Созданные предварительные просмотры виджетов позволяют создавать динамические, персонализированные предварительные просмотры ваших виджетов, которые точно отражают то, как они будут выглядеть на главном экране пользователя. Они предоставляются через API push-уведомлений, что означает, что ваше приложение предоставляет предварительный просмотр в любой момент своего жизненного цикла без получения явного запроса от хоста виджета.
Чтобы улучшить работу с виджетом в вашем приложении, предоставьте сгенерированный предварительный просмотр виджета на устройствах Android 15 и более поздних версий, масштабированный предварительный просмотр виджета (путем указания previewLayout ) для устройств Android 12–14 и previewImage для более ранних версий.
Для получения дополнительной информации см. раздел «Расширьте возможности своего приложения с помощью обновлений в реальном времени и виджетов на YouTube».
Настройте ваше приложение для предварительного просмотра сгенерированных виджетов.
Чтобы отображать сгенерированные предварительные просмотры виджетов на устройствах Android 15 или более поздних версий, сначала установите значение compileSdk равным 35 или более поздней версии в файле build.gradle модуля, чтобы иметь возможность предоставлять RemoteViews для выбора виджетов.
Затем приложения могут использовать setWidgetPreview либо в GlanceAppWidgetManager , либо AppWidgetManager . Во избежание злоупотреблений и снижения проблем со здоровьем системы, setWidgetPreview является API с ограничением количества вызовов. По умолчанию установлено ограничение примерно в два вызова в час.
Сгенерируйте обновленный предварительный просмотр с помощью Jetpack Glance.
Для виджетов, созданных с помощью Jetpack Glance, выполните следующие действия:
Переопределите функцию
GlanceAppWidget.providePreview, чтобы предоставить компонуемое содержимое для предварительного просмотра. Как и вprovideGlance, загрузите данные вашего приложения и передайте их в компонуемое содержимое виджета, чтобы гарантировать отображение точных данных в предварительном просмотре. В отличие отprovideGlance, это единая композиция без перекомпозиции или эффектов.Вызовите
GlanceAppWidgetManager.setWidgetPreviews, чтобы сгенерировать и опубликовать предварительный просмотр.
В системе нет функции обратного вызова для предоставления предварительного просмотра, поэтому ваше приложение должно самостоятельно решать, когда вызывать setWidgetPreviews . Стратегия обновления зависит от сценария использования вашего виджета:
- Если виджет содержит статическую информацию или представляет собой быстрое действие, настройте предварительный просмотр при первом запуске приложения.
- Предварительный просмотр можно настроить после получения данных приложением; например, после входа пользователя в систему или первоначальной настройки.
- Вы можете настроить периодическое обновление предварительного просмотра с выбранной периодичностью.
Устранение неполадок с созданными предварительными просмотрами
Распространенная проблема заключается в том, что после создания предварительного просмотра изображения, значки или другие элементы могут отсутствовать на изображении предварительного просмотра относительно размера ячейки виджета. Этот размер ячейки определяется параметрами targetCellWidth и targetCellHeight , если они указаны, или параметрами minWidth и minHeight в файле информации поставщика виджета приложения .
Это происходит потому, что Android по умолчанию отображает только элементы, которые должны быть видны при минимальном размере виджета. Другими словами, Android по умолчанию устанавливает previewSizeMode в SizeMode.Single . Он использует android:minHeight и android:minWidth в XML-файле информации о поставщике виджета приложения, чтобы определить, какие элементы следует отрисовывать.
Чтобы исправить это, переопределите previewSizeMode в вашем GlanceAppWidget и установите его значение равным SizeMode.Responsive , указав набор значений DpSize . Это сообщит Android все необходимые размеры макета для отображения предварительного просмотра, что гарантирует корректное отображение всех элементов.
Оптимизируйте под конкретные форм-факторы. Укажите 1 или 2 размера, начиная с минимального и следуя контрольным точкам вашего виджета. Укажите как минимум одно изображение для обратной совместимости . Соответствующие минимальные значения DP для разных размеров сетки можно найти в руководстве по проектированию виджетов .
Создать обновленный предварительный просмотр без Jetpack Glance
Вы можете использовать RemoteViews без Glance. В следующем примере загружается ресурс макета виджета в формате 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-макета, заданного размером виджета по умолчанию. Ранее предварительный просмотр виджета представлял собой статический ресурс изображения, что в некоторых случаях приводило к неточному отображению того, как виджеты выглядят после добавления на главный экран.
Для реализации масштабируемого предварительного просмотра виджетов используйте атрибут previewLayout элемента appwidget-provider , чтобы предоставить XML-макет:
<appwidget-provider
android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Мы рекомендуем использовать ту же компоновку, что и у фактического виджета, с реалистичными значениями по умолчанию или тестовыми значениями. В большинстве приложений используются одни и те же previewLayout и initialLayout . Рекомендации по созданию корректных макетов предварительного просмотра см. в следующем разделе этой страницы.
Мы рекомендуем указывать атрибуты previewLayout и previewImage , чтобы ваше приложение могло использовать previewImage в случае, если устройство пользователя не поддерживает previewLayout . Атрибут previewLayout имеет приоритет над атрибутом previewImage .
Обратная совместимость с предварительным просмотром виджетов.
Чтобы в Android 11 (уровень API 30) или более ранних версиях средства выбора виджетов отображали предварительный просмотр вашего виджета, или в качестве запасного варианта для сгенерированного предварительного просмотра, укажите атрибут previewImage .
Если вы измените внешний вид виджета, обновите изображение предварительного просмотра.
Создавайте точные предварительные просмотры, включающие динамические элементы.

В этом разделе объясняется рекомендуемый подход к отображению нескольких элементов в предварительном просмотре виджета для виджета с представлением коллекции — то есть виджета, использующего ListView , GridView или StackView . Это не относится к предварительному просмотру сгенерированных виджетов.
Если ваш виджет использует одно из этих представлений, создание масштабируемого предварительного просмотра путем непосредственного указания фактического макета виджета ухудшает пользовательский опыт, когда в предварительном просмотре виджета не отображаются элементы. Это происходит потому, что данные представления коллекции устанавливаются динамически во время выполнения, и это выглядит примерно так, как показано на рисунке 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_previe"
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>