Widgets have been a core part of the Android user experience for a long time, with many apps using widgets to increase user engagement. Users enjoy using widgets because they can use app functionality without opening the app and can customize the device’s home screen.
Android 12 updates the existing Widget API and reinvents the design of widgets to fit the “Material You” design language. These updates help you use the theme colors and rounded corners of your device to build more aesthetically pleasing widgets, improving the discoverability and visual look of widgets when searched and placed.
▽ Comparison of light and dark themes before update (Android 11) and after update (Android 12)
In this series, we’ll take you through updating widgets for Android 12. In this article, we’ll make some simple changes to make your widgets look more polished on Android 12 devices and provide a consistent user experience on older devices. In the second article, we’ll learn about new apis that make widgets more personalized, responsive, and interactive.
Visual change
For users, the most obvious visual changes are undoubtedly style and design changes. Updating visual elements, such as colors and rounded corners, gives users a fresh look. To add these modifications, we recommend that you create a custom theme.
Add dynamic colors
Material You aims to provide a more personalized user experience. In Android 12, dynamic colors help keep your widgets consistent with other widgets and your system. Micro parts you can use the system default Theme. The Theme of the DeviceDefault. DayNight, and used in the UI elements of micro Theme color attribute. Check out the Material Design update overview video for more details.
For devices with AN SDK level lower than 31, you need to create a custom theme that inherits from DeviceDefault.
values/themes.xml
<style name="Theme.AppWidget.AppWidgetContainer"
parent="@android:style/Theme.DeviceDefault" />
Copy the code
For devices with SDK level 31, use the theme deviceDefault.daynight to create a custom theme.
values-v31/themes.xml
<style name="Theme.AppWidget.AppWidgetContainer"
parent="@android:style/Theme.DeviceDefault.DayNight" />
Copy the code
- values/themes.xml
- values-v31/themes.xml
Or, if your application doesMaterial Components, you can use
Theme.MaterialComponents.DayNight
As a base theme rather than being usedTheme.DeviceDefault
.
To enable your widget to dynamically adapt system colors, you can configure the theme to your widget and use the theme color properties on other views of the widget.
layout/widget_checkbox_list_title_region.xml ... <TextView android:id="@+id/checkbox_list_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="8dp" android:layout_weight="1" android:text="@string/grocery_list" android:textColor="? android:attr/textColorPrimary" /> <ImageButton android:layout_width="@dimen/widget_element_min_length" android:layout_height="@dimen/widget_element_min_length" android:background="? android:attr/selectableItemBackground" android:clickable="true" android:contentDescription="@string/add_button_grocery_list_content_description" android:src="@drawable/ic_add_24" android:tint="? android:attr/colorAccent" /> ...Copy the code
- layout/widget_checkbox_list_title_region.xml
△ Static vs. dynamic colors in light/dark themes
Rounded corners
Starting with Android 12, rounded corners are automatically applied to widgets. This also means that rounded corners cut out parts of the widget. To avoid such problems and provide a look and feel consistent with other widgets and systems, you can add rounded corners to the widget’s background using system_app_widget_background_radius, Add rounded corners to the view in the widget using system_app_widget_inner_radius. The latter value must be 8dp less than system_app_widget_background_radius.
When adding the above changes, be aware that if your widgets contain content near the corner area, they may be clipped. To solve this problem, you need to add enough padding to avoid conflicts between the content of the widget and the rounded corners.
values/attrs.xml <declare-styleable name="AppWidgetAttrs"> <attr name="appWidgetPadding" format="dimension" /> <attr name="appWidgetInnerRadius" format="dimension" /> <attr name="appWidgetRadius" format="dimension" /> </declare-styleable> values/themes.xml <style name="Theme.AppWidget.AppWidgetContainerParent" parent="@android:style/Theme.DeviceDefault"> <! <item name="appWidgetRadius">16dp</item> <! -- The rounded radius of the edge of the view inside the widget. Its value is 8dp or less than appWidgetRadius --> <item name="appWidgetInnerRadius">8dp</item> </style> <style name="Theme.AppWidget.AppWidgetContainer" parent="Theme.AppWidget.AppWidgetContainerParent"> <! <item name="appWidgetPadding">16dp</item> </style> values-v31/themes.xml <style name="Theme.AppWidget.AppWidgetContainerParent" parent="@android:style/Theme.DeviceDefault.DayNight"> <item name="appWidgetRadius"> @android:dimen/system_app_widget_background_radius</item> <item name="appWidgetInnerRadius"> @android:dimen/system_app_widget_inner_radius</item> </style> values/styles.xml <style name="Widget.AppWidget.AppWidget.Container" parent="android:Widget"> <item name="android:id">@android:id/background</item> <item name="android:background"> ? android:attr/colorBackground</item> </style>Copy the code
- values/attrs.xml
- values/themes.xml
- values-v31/themes.xml
- values/styles.xml
If you have
minTargetSDK
Less than 21, then you need to provide the style for SDK version 21, because inDrawable objectFor use onandroid:attr/colorBackground
At least SDK version 21 is required.
Now that you have created the theme, you can set styles on the layout of the widget.
layout/widget_grocery_list.xml
<LinearLayout
style="@style/Widget.AppWidget.AppWidget.Container">
...
</LinearLayout>
Copy the code
- layout/widget_grocery_list.xml
Compare the original style with auto-rounded corners and the effect with rounded corners and padding
The transition
Android 12 provides a transition effect when apps are opened via widgets. This transition effect is handled automatically by the system and does not appear on older versions of Android. To enable this effect, you need to specify an ID on the widget layout root element and set its value to Android: ID /background.
<LinearLayout
android:id="@android:id/background">
...
</LinearLayout>
Copy the code
Slow play animation for transition effects
If your widget uses a broadcast Trampoline, that is, your widget creates a PendingIntent when the user clicks it and starts the Activity with a broadcast or service, then this transition animation will not take effect in this case.
Optimization of microcomponent selector
preview
Android 12 includes a new and improved widget selector. Instead of using static drawable resources, the new widget selector uses XML layouts to dynamically create scaled widget previews.
If your widget does not contain dynamic elements, such as a ListView or GridView, you can preview the layout of the widget.
To implement the preview, you need to set the default values directly onto the original layout.
<TextView
style="@style/Widget.AppWidget.Checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/widget_title_preview" />
<TextView
style="@style/Widget.AppWidget.Checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/widget_subject_preview" />
Copy the code
Setting default values on the layout may introduce a small amount of delay because placeholder values are enabled first before the actual values. To avoid this problem, you can create a separate layout file for the preview and enable a custom preview theme.
<resources> <! <attr name="widgetTitlePreview" format="string" /> <attr name="widgetTitlePreview" format="string" /> <! - a statement style - > < style name = "Theme. MyApp. Widget" parent "=" @ style/Theme. DeviceDefault. DayNight. AppWidget "> < item name="widgetTitlePreview"></item> <item name="widgetSubjectPreview"></item> </style> <style name="Theme.MyApp.Widget.Preview"> <item name="widgetTitlePreview">Preview Title</item> <item name="widgetSubjectPreview">Preview Subject</item> </style> </resources>Copy the code
After you create a preview theme, you can apply it to preview elements in your layout.
layout/my_widget_preview.xml <LinearLayout ... > < include layout = "@ layout/widget_header" android: theme. = "@ style/theme MyApp. Widget. The Preview" / > < / LinearLayout > layout/my_widget_actual.xml <LinearLayout ... > <include layout="@layout/widget_header" Android :theme= "@style/ theme.myapp. Widget" /> </LinearLayout>Copy the code
Finally, you need to set the layout of the widget to the previewLayout property of the AppWidget-Provider.
xml/app_widget_info_checkbox_list.xml
<appwidget-provider
android:previewLayout="@layout/widget_grocery_list"
...
/>
Copy the code
- xml/app_widget_info_checkbox_list.xml
Compare static preview effect with zoom preview effect
For listViews, GridViews, or stacks that display multiple elements, there is no way to set default values directly on the layout. For these views, you can create another layout for the widget preview and set fixed values in the layout.
To do this, the recommended best practice is to use the
tag to reuse part of the layout to enable default values without copying the entire layout. You can set the new layout to the previewLayout property of the AppWidget-Provider.
describe
You can also set the Description property to display as a description on the widget selector. Although this is optional, providing a description helps the user better understand the functionality of the widget.
app_widget_info_checkbox_list.xml <appwidget-provider android:description="@string/app_widget_grocery_list_description" . />Copy the code
△ Description of microcomponents
conclusion
In this article, we show you how to update your widget design and provide a better user experience in the widget selector. The above can quickly update your widgets for Android 12, and your users can see the difference very intuitively.
But that’s not the whole story. In the next article, we’ll learn about new apis that can make your widgets more personalized, responsive, and interactive.
Please click here to submit your feedback to us, or share your favorite content or questions. Your feedback is very important to us, thank you for your support!