Чтобы улучшить работу с виджетом в вашем приложении, предоставьте сгенерированный предварительный просмотр виджета на устройствах Android 15 и более поздних версий, масштабированный предварительный просмотр виджета (путем указания previewLayout ) для устройств Android 12–14 и previewImage для более ранних версий.
Созданные предварительные просмотры виджетов позволяют создавать динамические, персонализированные предварительные просмотры для ваших виджетов, которые точно отражают то, как они будут выглядеть на главном экране пользователя. Для Android 15 и выше они предоставляются через API push-уведомлений, то есть ваше приложение предоставляет предварительный просмотр в любой момент своего жизненного цикла без получения явного запроса от хоста виджета.
Для получения дополнительной информации см. раздел «Расширьте возможности своего приложения с помощью обновлений в реальном времени и виджетов на YouTube».
Добавить сгенерированные предварительные просмотры
Чтобы отображать сгенерированные предварительные просмотры виджетов на устройствах 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-макета, заданного размером виджета по умолчанию. Ранее предварительный просмотр виджета представлял собой статический ресурс изображения, что в некоторых случаях приводило к неточному отображению того, как виджеты выглядят после добавления на главный экран.
Для реализации масштабируемого предварительного просмотра виджетов используйте атрибут 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 .
Если вы измените внешний вид виджета, обновите изображение предварительного просмотра.
Этот атрибут также используется в качестве резервного варианта для сгенерированных предварительных просмотров, если вы не установили его с помощью 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>