Enhance your widget

This page includes details for optional widget enhancements that are available starting in Android 12 (API level 31). These features are optional, but they’re straightforward to implement and improve your users’ widget experience.

Add device theming

Starting in Android 12, a widget can use the device theme colors for buttons, backgrounds, and other components. This enables smoother transitions and consistency across different widgets.

In the following example, the device theme color is “purplish”, causing the accent color and widget background to adapt. You can achieve this by using the system's default theme (@android:style/Theme.DeviceDefault.DayNight) and its color attributes. Some commonly-used color attributes are:

  • ?android:attr/colorAccent
  • ?android:attr/colorBackground
  • ?android:attr/textColorPrimary
  • ?android:attr/textColorSecondary
Widget in light mode theme
Figure 1: Widget in light theme
Widgets in dark mode theme
Figure 2: Widget in dark theme

Backward-compatibility with dynamic colors

We recommend creating a custom theme and overriding it for Android 12. The following examples show how to do this with various types of XML files:

/values/styles.xml

<resources>
  <style name="MyWidget.TextView">
    <item name="android:textColor">@color/my_text_color</item>
  </style>
  <style name="MyWidgetTheme" parent="Theme.DeviceDefault.Light">
    <item name="textViewStyle">@style/MyWidget.TextView</item>
  </style>
</resources>

/values-31/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="Theme.DeviceDefault.DayNight" />
</resources>

/layout/my_widget_layout.xml

<resources>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:theme="@style/MyWidgetTheme" />
</resources>

Enable voice support

App Actions enable Google Assistant to display widgets in response to relevant user voice commands. By configuring your widget to respond to built-in intents (BII), your app can proactively display widgets on Assistant surfaces such as Android and Android Auto. Users have the option to pin widgets displayed by Assistant to their launcher, encouraging future engagement.

For example, you could configure the workout summary widget for your exercise app to fulfill the user voice commands that trigger the GET_EXERCISE_OBSERVATION BII. Now, Assistant will proactively display your widget when users trigger this BII by making requests like, "Hey Google, how many miles have I run this week on ExampleApp?"

There are dozens of BIIs covering several categories of user interaction, enabling almost any Android app to enhance their widgets for voice. To get started, see Integrate App Actions with Android widgets.

Improve your app's widget picker experience

Android 12 enables you to improve the widget picker experience for your app by adding dynamic widget previews and widget descriptions.

Add scalable widget previews to the widget picker

Starting in Android 12, the widget preview displayed in the widget picker consists of a scalable preview, which you’ll provide as an XML layout set to the widget's default size. Previously, the widget preview was a static drawable resource, in some cases leading to previews not accurately reflecting widgets after they were added to the home screen.

To implement scalable widget previews, use the previewLayout attribute of the appwidget-provider element to provide an XML layout instead:

<appwidget-provider
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>

Ideally, this should be the same layout as the actual widget with realistic default or test values. Most apps should use the same previewLayout and initialLayout. For guidance on creating accurate preview layouts, see Recommended approaches for building accurate previews in this document.

We recommend specifying both the previewLayout and previewImage attributes, so that your app can fall back to using previewImage if the user's device doesn’t support previewLayout. The previewLayout attribute takes precedence over the previewImage attribute.

Recommended approaches for building accurate previews

To implement scalable widget previews, use the previewLayout attribute of the appwidget-provider element to provide an XML layout instead:

<appwidget-provider
    …
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
Figure 3: A widget preview that by default appears in a 3x3 area, but can fit in a 3x1 area because of its XML layout

To display an accurate preview, you can directly provide the actual widget layout with default values set. For example:

  • Setting the android:text="@string/my_widget_item_fake_1" for TextView elements.

  • Setting a default or placeholder image or icon (android:src="@drawable/my_widget_icon") for ImageView components.

Otherwise, the preview may end up showing incorrect or empty values. An important benefit of this approach is that you can provide localized preview content.

For recommended approaches for more complex previews that contain ListView, GridView, or StackView, see Build accurate previews that include dynamic items for details.

Backward-compatibility with scalable widget previews

To enable widget pickers on Android 11 (API level 30) or lower to show previews of your widget, continue specifying the previewImage attribute.

If you make changes to the widget’s appearance, make sure to also update the preview image.

Add a description for your widget

Starting in Android 12, you should provide a description for the widget picker to display for your widget.

Sample widget picker showing a widget and its description
Figure 4: Widget picker showing a widget and its description

Provide a description for your widget using the description attribute of appwidget-provider:

<appwidget-provider
    android:description="@string/my_widget_description">
</appwidget-provider>

Your app can use the descriptionRes attribute on previous versions of Android, but it will be ignored by the widget picker.

Enable smoother transitions

Starting in Android 12, launchers provide a smoother transition when a user launches your app from a widget.

To enable this improved transition, use @android:id/background or android.R.id.background to identify your background element:

// Top level layout of the widget.
<LinearLayout
    android:id="@android:id/background">
</LinearLayout>

Your app can use @android:id/background in previous versions of Android without breaking, but it will be ignored.

Use runtime modification of RemoteViews

Starting in Android 12, you can take advantage of several new RemoteViews methods that allow for runtime modification of RemoteViews attributes. See the RemoteViews API reference for the full list of added methods.

The following code example shows how to use a few of the new methods.

Kotlin

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList())

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP)

Java

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList());

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP);