在 Android 12 中使用你的微件做更多事情!

原文链接

在 Android 12 中使用你的微件做更多事情!

这篇文章是我写的关于更新 Android 12 微件的小连载文章的第二篇。在上一部分中,我们探索了一些简单的方法来实现对app用户高度可见的可视化更新。在本部分中,我们将介绍一些更高级的功能,使您的微件更具交互性,更易于配置,并在 Android 12 上提供更好的UI体验。

更简单的配置

在 Android 12 之前,重新配置微件意味着用户必须删除现有的微件,并使用新配置再次添加。Android 12 以多种方式改进了微件的配置方式,并帮助用户更轻松地个性化微件。

允许用户重新配置已放置的微件

可重新配置的微件允许用户根据其所需设置自定义微件。使用 Android 12,他们不再需要删除和重新添加微件来调整这些设置。

您可以调整微件的大小并重新配置其设置

要启用此功能,请在 appwidget-provider 中将 widgetFeatures 属性设置为 reconfigurable

xml/app_widget_info_checkbox_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<appwidget-provider
    android:configure="com.example.android.appwidget.ListWidgetConfigureActivity"
    android:widgetFeatures="reconfigurable"
    ... />

默认配置

如果您的微件可以依赖默认设置,您可以跳过启动初始配置 activity,并在 Android 12 中使用默认配置设置微件。

让我们概览下示例微件,看看它是如何工作的。在这个用例中,我们希望用户能够在两个不同的微件布局中进行选择,杂货店列表和待办事项列表。我们希望使用杂货店列表作为默认设置,因此用户不需要执行配置步骤,除非他们想切换到待办事项列表。

为了实现这个用例,您可以存储用户的选择,并在没有事先选择的情况下返回杂货店清单作为默认值。

ListAppWidget.kt
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
val layoutId = ListSharedPrefsUtil.loadWidgetLayoutIdPref(
    context, appWidgetId
)
val remoteViews = if (layoutId == R.layout.widget_grocery_list) {
    // 使用dp指定你想用于指定布局尺寸的最大宽度和高度
    val viewMapping = mapOf(
        SizeF(150f, 150f) to constructRemoteViews(
            R.layout.widget_grocery_list
        ), SizeF(250f, 150f) to constructRemoteViews(
            R.layout.widget_grocery_grid
        )
    )
        RemoteViews(viewMapping)
    } else {
        constructRemoteViews(
            layoutId
        )
    }
appWidgetManager.updateAppWidget(appWidgetId, remoteViews)

现在,微件已配置为提供默认配置,您需要将 configuration_optional 标志设置给 widgetFeatures 属性。这将跳过额外的配置步骤,并将微件直接放在用户的主屏幕上。执行此操作时,请确保还添加了 reconfigurable 标志,以便用户可以在以后更改已应用的默认设置。

xml/app_widget_info_checkbox_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<appwidget-provider 
    android:configure="com.example.android.appwidget.ListWidgetConfigureActivity"
    android:widgetFeatures="reconfigurable|configuration_optional"
    ... />

通过此更改,当用户将微件添加到主屏幕时,它会自动使用杂货店列表布局。由于配置 activity 被添加到 appwidget-provider 的 configure 属性中,因此当用户长按该微件并单击编辑/重新配置按钮时,activity 将启动。

当用户单击编辑/重新配置按钮时,将启动 ListWidgetConfigureActivity

当用户配置微件时,此新配置存储在 ListWidgetConfigureActivity 中。

ListWidgetConfigureActivity.kt
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
private fun onWidgetContainerClicked(@LayoutRes widgetLayoutResId: Int) {
    ListSharedPrefsUtil.saveWidgetLayoutIdPref(this, appWidgetId, widgetLayoutResId)
    // 配置 activity 负责更新 app 的微件
    val appWidgetManager = AppWidgetManager.getInstance(this)
    ListAppWidget.updateAppWidget(this, appWidgetManager, appWidgetId)
    // 确保我们传回原始的 appWidgetId
    val resultValue = Intent()
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    setResult(RESULT_OK, resultValue)
    finish()
}

新的和改进的 API

当谈到运行 Android 的设备时,有许多不同的外形因素可供选择,无论是手机、平板电脑、折叠式还是其他类型的产品。Android 12 引入了精细的尺寸属性和更灵活的布局,使微件更易于定制,在不同的设备和屏幕尺寸下更可靠。

微件大小限制

除了现有的 minWidthminHeightminResizeWidth 和 minResizeHeight 之外,Android 12 还添加了新的 appwidget-provider 属性。

您可以使用新的 maxResizeWidth 和 maxResizeHeight 属性定义用户可以调整微件大小的最大高度和宽度。新的 targetCellWidth 和 targetCellHeight 属性定义设备主屏幕上的默认微件大小。

定义 targetCellWidth 和 targetCellHeight 属性后,运行 Android 12 的设备将使用这些属性,而不是 minWidth 和 minHeight。运行 Android 11 及更低版本的设备将继续使用 minWidth 和 minHeight 属性。

注意: targetCellWidth 和 targetCellHeight 属性用单元格定义,而 maxResizeWidth 和 maxResizeHeight 属性用 dp 定义。

xml/app_widget_info_checkbox_list.xml
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<appwidget-provider
    android:maxResizeWidth="240dp"
    android:maxResizeHeight="180dp"
    android:minWidth="180dp"
    android:minHeight="110dp"
    android:minResizeWidth="180dp"
    android:minResizeHeight="110dp"
    android:targetCellWidth="3"
    android:targetCellHeight="2"
    ... />

在Android 12中,使用 targetCellWidth 和 targetCellHeight 属性代替 minWidth 和 minHeight

响应式布局

尽管使用大小限制可以帮助用户根据需要调整微件的大小,但您可能希望根据微件的大小提供不同的布局和内容类型。这也使系统能够以不同的大小显示微件,而无需唤醒 app。

要实现这一点,首先为一系列尺寸创建一组布局,然后调用 updateAppWidget() 函数并传递布局集合,如下面的示例所示。当微件尺寸更改时,系统会自动更改布局。

<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
val viewMapping: MutableMap<SizeF, RemoteViews> = mutableMapOf()
// 使用dp指定你想用于指定布局尺寸的最大宽度和高度
val viewMapping = mapOf(
    SizeF(150f, 110f) to RemoteViews(
        context.packageName,
        R.layout.widget_grocery_list
    ),
    SizeF(250f, 110f) to RemoteViews(
        context.packageName,
        R.layout.widget_grocery_grid
    ),
)
appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))
//...

当用户调整微件的大小时,响应式布局提供了更好的可用性

复选按钮

用户无需启动 app,就可以使用 Android 12中 的微件做更多的事情!使用新的复选按钮,您可以使微件更具交互性。这不会改变微件的无状态性质,但允许您添加一个监听器来观察状态更改事件。当发生状态更改事件时,可以调用RemoteResponse.fromPendingIntent() ()并在监听器中传入 PendingIntent

ItemsCollectionAppWidget.kt
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
remoteViews.setOnCheckedChangeResponse(
    R.id.item_switch,
    RemoteViews.RemoteResponse.fromPendingIntent(
        onCheckedChangePendingIntent
    )
)

另一方面,如果您的微件有一个控件列表,则不应在集合的单个条目上设置 PendingIntent,因为这会导致性能低下。在这种情况下,在集合上设置一个 PendingIntent 模板,调用 RemoteResponse.fromFillInIntent(),并在发生状态更改事件时在监听器中传入 fillInIntent。

ItemsCollectionAppWidget.kt
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
remoteViews.setOnCheckedChangeResponse(
    R.id.item_switch,
    RemoteViews.RemoteResponse.fromFillInIntent(
        onCheckedChangeFillInIntent
    )
)

微件与复选按钮更具交互性

针对集合简化后的 RemoteViews

Android12 引入了一个新的 API 来简化传递集合以填充微件中的列表的过程。以前,如果要用项目集合填充 ListView、 GridViewStackView 或其他 view,则需要实现 RemoteViewsService 以返回 RemoteViewsFactory。使用新的 setRemoteAdapter() API,您只需通过主 RemoteViews 传递一个集合。我们也正在开发 androidx 补丁,以支持在旧版本的 Android 上使用此 API。

如果集合不使用固定的布局集,则可以使用 setViewTypeCount() 函数设置此集合中 RemoteViews 将使用的最大布局 id 数。

ItemsCollectionAppWidget.kt
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
remoteViews.setRemoteAdapter(
    R.id.items_list_view,
    RemoteViews.RemoteCollectionItems.Builder()
        .addItem(/* id= */ ID_1, RemoteViews(...))
        .addItem(/* id= */ ID_2, RemoteViews(...))
        //...
        .setViewTypeCount(MAX_NUM_DIFFERENT_REMOTE_VIEWS_LAYOUTS)
        .build()
)

总结

就这样!将您现有的微件更新到 Android 12 将立即带来更新颖的外观,并使您的微件更具交互性。

既然您已经阅读了本文中有关可配置性和新的或改进的 API 的内容,请查看第一部分,了解如何更新微件的设计,并在微件选择器中提供更好的用户体验。想要了解更多,请查看本文中使用的示例代码

如果您正在构建新的微件,请密切关注未来的公告。我们正在努力让构建新的微件更加容易!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值