创建简单的 widget

尝试使用 Compose 方式
Jetpack Compose 是推荐用于 Android 的界面工具包。了解如何使用 Compose 风格的 API 构建 widget。

应用微件是可以嵌入其他应用(如主屏幕)并接收定期更新的微型应用视图。这些视图在界面中称为微件,您可以使用应用微件提供程序(或微件提供程序)发布微件。容纳其他 widget 的应用组件称为应用 widget 宿主(或 widget 宿主)。图 1 显示了一个示例音乐 widget:

音乐 widget 示例
图 1. 音乐 widget 示例。

本文档介绍如何使用 widget 提供程序发布 widget。如需详细了解如何创建您自己的 AppWidgetHost 来托管应用 widget,请参阅构建 widget 托管应用

如需了解如何设计微件,请参阅应用微件概览

微件组件

如需创建 widget,您需要以下基本组件:

AppWidgetProviderInfo 对象
描述 widget 的元数据,例如 widget 的布局、更新频率和 AppWidgetProvider 类。AppWidgetProviderInfo在 XML 中定义的,如本文档中所述。
AppWidgetProvider
定义允许您以编程方式与 widget 连接的基本方法。通过它,您会在 widget 更新、启用、停用或删除时收到广播。您需要在清单中声明 AppWidgetProvider,然后按照本文档中的说明实现它。
查看布局
定义 widget 的初始布局。布局是在 XML 中定义的,如本文档中所述。

图 2 显示了这些组件如何融入整个应用 widget 处理流程。

应用 widget 处理流程
图 2. 应用 widget 处理流程。

如果您的 widget 需要用户配置,请实现应用 widget 配置 activity。此 activity 可让用户修改 widget 设置,例如时钟 widget 的时区。

  • 从 Android 12(API 级别 31)开始,您可以提供默认配置,并允许用户稍后重新配置 widget。如需了解详情,请参阅使用 widget 的默认配置允许用户重新配置已放置的 widget
  • 在 Android 11(API 级别 30)或更低版本中,每当用户将 widget 添加到其主屏幕时,系统都会启动此 activity。

我们还建议进行以下改进:灵活的 widget 布局各种增强功能高级 widget集合 widget构建 widget 宿主

声明 AppWidgetProviderInfo XML

定义元数据设置(例如默认单元格大小、调整大小限制和更新频率)在传统视图和基于概览的 widget 中完全相同。

如需了解如何定义和配置元数据 XML 文件,请参阅 Glance 文档中的“Compose-first 声明 AppWidgetProviderInfo XML 部分”。

使用 AppWidgetProvider 类处理 widget 广播

平台底层的广播接收器机制、清单声明过滤器和生命周期事件循环已统一。在 Compose 优先开发中,这些广播使用 GlanceAppWidgetReceiver 封装容器进行编排。

如需了解如何在清单中注册接收器并实现与 Hilt 兼容的生命周期替换,请参阅 Glance 文档中的“Compose-first 使用 AppWidgetProvider 类处理广播部分。

创建 widget 布局

您必须在 XML 中定义 widget 的初始布局,并将其保存在项目的 res/layout/ 目录中。如需了解详情,请参阅设计准则

如果您熟悉布局,那么创建微件布局非常简单。不过,请注意,微件布局基于 RemoteViews,并不是每种布局或视图微件都受其支持。您无法使用自定义视图或 RemoteViews 支持的视图的子类。

RemoteViews 还支持 ViewStub,它是一个大小为零的不可见 View,您可以使用它在运行时以懒散的方式扩充布局资源。

对有状态行为的支持

Android 12 使用以下现有组件新增了对有状态行为的支持:

微件仍然无状态。您的应用必须存储状态并注册状态更改事件。

显示有状态行为的购物清单 widget 示例
图 3. 有状态行为示例。

以下代码示例展示了如何实现这些组件。

Kotlin

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
        R.id.my_checkbox,
        RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Java

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true);

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2);

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));

提供两个布局:一个的目标设备搭载 Android 12 或更高版本(位于 res/layout-v31 中),另一个的目标设备搭载以前的 Android 11 或更低版本(位于默认的 res/layout 文件夹中)。

实现圆角

计算外部背景和内部比例半径是标准且共享的。在“Compose 优先”开发中,可以在 Kotlin 中与自定义主题资源一起动态设置此属性。

如需为旧版 Android 设备实现圆角半径或设置动态样式,请参阅 Glance 文档中的“Compose-first 实现圆角”部分