为 Android 12 更新你的微件(Widget)

原文连接

很长时间以来,微件(Widgets) 一直是Android核心体验的一部分,许多应用程序有效地使用微件来增加用户参与度。用户喜欢微件,因为它能够在不启动应用程序的情况下使用应用程序的功能,并自定义设备的主屏幕。

Android 12更新了现有的微件API,并修改了微件的设计,使之与“Material You”的设计语言保持一致。这些更改允许您使用设备主题颜色和圆角来构建更好看的微件,同时增强 搜索和放置微件 的可发现性和视觉效果。

更改前(Android 11)与更改后的浅色和深色主题(Android 12)相对比

在这个迷你系列文章中,我们将了解如何为Android 12更新您的微件。在这一部分中,我们将看到一些简单的更改,这些更改将使您的微件在运行Android 12的设备上看起来很棒,同时在旧版本的Android上提供一致的体验。在第二部分中,我们将了解下新的API,它将使您的微件更加个性化、响应更灵敏,并提供更多的交互性。

视觉变化

毫无疑问,风格和设计的变化对用户来说是最明显的。更新例如颜色和(圆)角半径之类的视觉元素,可立即呈现更清爽的外观。要开始实现这些更改,我们建议创建一个自定义主题。

添加动态颜色

Material You 的目标是实现更个性化的用户体验。在Android 12上,动态颜色使您的微件与其他微件和系统更加一致。微件可以使用系统的默认主题Theme.DeviceDefault.DayNight,并在微件的UI元素上使用主题颜色属性。

要做到这一点,你需要为低于31的版本从父DeviceDefault创建一个自定义主题。 

values/themes.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.AppWidget.AppWidgetContainer" 
    parent="@android:style/Theme.DeviceDefault" />

对于版本31,使用父主题DeviceDefault.DayNight创建一个自定义主题。

values-v31/themes.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.AppWidget.AppWidgetContainer"  
    parent="@android:style/Theme.DeviceDefault.DayNight" />

或者,如果你的app使用Material Components,则可以使用Theme.MaterialComponents.DayNight作为基本主题,而不是Theme.DeviceDefault

要使微件动态地采用系统颜色,请将此主题指定给微件,并在其他views上使用主题颜色属性。

layout/widget_checkbox_list_title_region.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
...
<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" />
...

静态颜色 vs. 浅色/深色 主题中的动态颜色

圆角

从Android 12开始,圆角自动应用于微件。这意味着微件的内容可能会被应用的拐角遮罩切断。为了避免这种情况,并为其他微件和系统提供更一致的外观和用户体验,您可以使用  system_app_widget_background_radius 向微件的轮廓添加圆角,使用  system_app_widget_inner_radius 向微件内的 views 添加圆角。这个值应该比 system_app_widget_background_radius小8dp。

在执行此操作时,请记住,如果您的微件的内容靠近其角落,则此内容可能会被裁剪。要解决这个问题,您需要添加足够的 padding,以避免微件的内容与圆角冲突。

values/attrs.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<declare-styleable name="AppWidgetAttrs">
    <attr name="appWidgetPadding" format="dimension" />    
    <attr name="appWidgetInnerRadius" format="dimension" />
    <attr name="appWidgetRadius" format="dimension" />
</declare-styleable>
values/themes.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.AppWidget.AppWidgetContainerParent" 
    parent="@android:style/Theme.DeviceDefault">
    <!-- 微件外部边界的半径,用以生成圆角。-->
    <item name="appWidgetRadius">16dp</item>
    <!-- 微件内部view边界的半径,用以生成圆角。它需要是8dp或小于 appWidgetRadius 的值。-->
    <item name="appWidgetInnerRadius">8dp</item>
</style>
<style name="Theme.AppWidget.AppWidgetContainer" 
    parent="Theme.AppWidget.AppWidgetContainerParent">
    <!-- 应用 padding 以避免微件的内容与圆角冲突。-->
    <item name="appWidgetPadding">16dp</item>
</style>
values-v31/themes.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<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
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<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>

如果你的 minTargetSDK 低于版本 21,则需要为版本 21 提供样式,因为在 drawables 中使用的 android:attr/colorBackground 要求 API 级别 为21。

现在您已经创建了一个主题,您可以在微件的布局上设置样式。

layout/widget_grocery_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<LinearLayout
    style="@style/Widget.AppWidget.AppWidget.Container">
    ...
</LinearLayout>

之前 vs. 自动圆角遮罩 vs. 应用 padding 的圆角

过渡效果

Android 12 在从微件启动 app 时提供了改进的过渡效果。这个过渡转场由系统自动处理,并且在旧版本的Android上不会显示。要启用它,您需要在微件布局的根元素上指定一个id并将其值设置为 android:id/background

<LinearLayout
    android:id="@android:id/background">
    ...
</LinearLayout>

慢速下的过渡效果

如果您的微件使用  broadcast trampolines ,这意味着您的微件在用户单击时创建一个 PendingIntent ,以从broadcast receiver 或 service 启动 activity,则不会使用此动画。

新的微件选择器改进

预览

Android 12有一个新的和改进的微件选择器。新的微件选取器不使用静态 drawable 资源,而是使用 XML 布局动态创建微件的缩放预览。

如果您的微件不包含动态元素,如 ListView 或GridView,您可以简单地使用微件的布局进行预览。

要实现这一点,需要将默认值直接设置为原始布局。

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<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" />

在布局上设置默认值可能会导致在应用实际值之前,假占位符值显示的稍微延迟。要防止出现这种情况,您也可以为预览创建单独的布局文件,并应用自定义预览主题。

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<resources>
    <!-- 声明属性 -->
    <attr name="widgetTitlePreview" format="string" />
    <attr name="widgetSubjectPreview" format="string" />
    <!-- 声明样式 -->
    <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>

一旦有了预览主题,就可以将其应用到布局中的预览项。 

layout/my_widget_preview.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<LinearLayout ...>
    <include layout="@layout/widget_header"
         android:theme=”@style/Theme.MyApp.Widget.Preview” /></LinearLayout>
layout/my_widget_actual.xml
<LinearLayout ...>
    <include layout="@layout/widget_header"
        android:theme=”@style/Theme.MyApp.Widget” />
</LinearLayout>

最后,您需要设置微件的布局,以指定为 appwidget-provider的 previewLayout 属性。

xml/app_widget_info_checkbox_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<appwidget-provider
    android:previewLayout="@layout/widget_grocery_list"
    ... 
/>

静态预览 vs. 缩放预览

对于 ListViewGridView 或 Stack中显示的多个项目,无法直接在布局上设置默认值。在这种情况下,您可以为微件预览创建另一个布局,并在此布局中设置多个硬编码项。

执行此操作时,最好不要复制整个布局,而是使用 <include> 标签来重用使用默认值的布局部分。 您可以将这个新布局设置为 appwidget-provider的 previewLayout 属性。  

描述

您还可以设置 description 属性,以提供要在微件选择器中显示的描述。虽然这是可选的,但提供描述可以帮助用户更好地理解微件的功能。

app_widget_info_checkbox_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<appwidget-provider
   android:description="@string/app_widget_grocery_list_description"
   ... 
/>

微件描述

总结

这并不难,对吧? 在这篇文章中,你已经了解了如何更新微件的设计,并在微件选择器中提供更好的用户体验。 这些都是很容易完成的任务,你可以开始为 Android 12 更新你的微件,你的用户会立即注意到视觉上的差异。  

但是,这还不是全部。在下一篇文章中,我们将了解下新的 API,它将使您的微件更加个性化、响应速度更快,并提供更多的交互性。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值