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.
There are two ways to achieve dynamic colors:
- Use the system's default theme
(
@android:style/Theme.DeviceDefault.DayNight
) in the root layout. - Use the new Material3 theme (
Theme.Material3.DynamicColors.DayNight
) from the material-components-android library, available since material-components-android v1.6.0.
Once the theme is set to the root layout, you can use some of the commonly-used color attributes in the root or any of its children to pick up the dynamic colors.
Here is a non-exhaustive list:
?android:attr/colorAccent
?android:attr/colorBackground
?android:attr/textColorPrimary
?android:attr/textColorSecondary
In the following example (using Material3 theme), the device theme color is “purplish,” causing the accent color and widget background to adapt for light and dark modes.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground"
android:theme="@style/Theme.Material3.DynamicColors.DayNight">
<ImageView
...
android:tint="?android:attr/colorAccent"
android:src="@drawable/ic_partly_cloudy" />
<!-- Other widget content -->
</LinearLayout>


Backward-compatibility with dynamic colors
Dynamic colors are only available in devices running Android 12
or above. To provide a custom theme for lower versions, create a default theme
with your custom colors and a new qualifier (values-v31
) using the default
theme attributes.
Here is an example using the Material3 theme:
/values/styles.xml
<resources>
<style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight">
<!-- Override default colorBackground attribute with custom color -->
<item name="android:colorBackground">@color/my_background_color</item>
<!-- Add other colors/attributes -->
</style>
</resources>
/values-v31/styles.xml
<resources>
<!-- Do not override any color attribute -->
<style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight" />
</resources>
/layout/my_widget_layout.xml
<resources>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="?android:attr/colorBackground"
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
on this page.
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>

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"
forTextView
elements.Setting a default or placeholder image or icon (
android:src="@drawable/my_widget_icon"
) forImageView
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.

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);