Android 12 上焕然一新的小组件: 美观、便捷和实用

您所在的位置:网站首页 安卓小组件插件怎么设置 Android 12 上焕然一新的小组件: 美观、便捷和实用

Android 12 上焕然一新的小组件: 美观、便捷和实用

2024-07-14 19:56| 来源: 网络整理| 查看: 265

本文原作者: 小虾米君,原文发布于: TechMerger

https://mp.weixin.qq.com/s/w_289RIXnb7wkT3c0b8nfQ

Google IO 2021 重磅介绍的 Android 12,号称历代设计变化最大的版本。其全新的 Material You 设计语言、流畅的动画特效再到焕然一新的小组件,都令人印象深刻。本文将聚焦小组件环节,谈谈它在重新设计之后的各种新特性和适配方法。

小组件在 Android 平台上命名为 AppWidget,有的时候还被翻译成小部件、小插件和微件。说的都是一个东西: 显示在 Launcher 上,能在 Logo 以外提供更多信息的特别设计。它方便用户免于打开 App 即可直接查看信息和进行简单的交互,在 PC 上、早前的 Symbian 上都有类似的设计。

前言

简要回顾下移动平台在小组件设计上的持续探索:

早期的 Android 版本缺乏美观,小组件更是常年未改。似乎除了天气、时钟等常用小组件以外鲜少使用,逐渐被人遗忘;

Windows Phone 的动态磁贴在自由尺寸的 Logo 上灵活展示信息的设计非常超前,奈何生态构建困难,早已退场;

Apple 向来稳重 (保守),直到 iOS 10 才引入小组件,但负一屏限制着它的发展。直到 iOS 14 的全面支持才大获成功,大有后来居上的态势;

VIVO 紧随其后重磅推出的 OriginOS 则将 Logo 和小组件完美融合,试图一统磁贴和小组件的概念,非常值得称赞;

也许是受到了友商们的持续刺激,Google 终于开始重新审视小组件这个元老级功能,并在 Android 12 里进行了重新设计、重新出发。

下面将结合代码实战,带领大家逐步感受 Android 12 里小组件的各项新特性和对应的适配方法。

1. 选择和展示的统一变化

事实上即使未做任何适配,在 12 上直接运行的小组件与 11 就有明显不同,主要表现在选择器和展示的效果。

以 Chrome 和 Youtube Music 的小组件为例:

可以看到 12 上的一些变化:

选择器

顶部悬浮搜索框,可以更加快速地找到目标小组件

小组件按照 App 自动折叠,避免无关的小组件占用屏幕空间

App 标题还对包含的小组件数目进行了提示

拖拽到桌面上之后小组件默认拥有圆角设计

11 上的小组件选择器不支持搜索而且无法折叠,拖拽到桌面上也是初始的直角效果。

2. 美观的圆角设计

健康信息越发重要,手撸一个展示今日步数的小组件,搭配 androidplot 开源框架展示详细的步数图表。

override fun onUpdate(...) { for (appWidgetId in appWidgetIds) { showBarChartToWidget(context, appWidgetManager, appWidgetId) } } private fun showBarChartToWidget(...) { // Create plot view. val plot = XYPlot(context, "Pedometers chart") ... // Set graph shape plot.setBorderStyle(Plot.BorderStyle.ROUNDED, 12f, 12f) plot.isDrawingCacheEnabled = true // Reflect chart's bitmap to widget. val bmp = plot.drawingCache val remoteViews = RemoteViews(context.packageName, R.layout.widget_pedometer) remoteViews.setBitmap(R.id.bar_chart, "setImageBitmap", bmp) appWidgetManager.updateAppWidget(appWidgetId, remoteViews) }

不用特别适配,直接运行到 12 上,就能有圆角效果。

但布局需要遵从如下两点建议:

四周的边角不要放置内容,防止被切掉

背景不要采用透明的、空的视图或布局,避免系统无法探测边界去进行裁切

事实上,系统预设了如下 dimension 以设置默认的圆角表现。

system_app_widget_background_radius: 小组件背景的圆角尺寸,默认 16dp,上限 28dp

system_app_widget_inner_radius: 小组件内部视图的圆角尺寸,默认 8dp,上限 20dp

system_app_widget_internal_padding: 内部视图的 padding 值,默认 16dp

看下官方的对于内外圆角尺寸的示意图。

注意:

这些 dimension 可以被 ROM 厂商或 3rd Launcher 修改,不一定能保证一致性的尺寸

官方没有说明小组件的内部视图如何才能应用上内部圆角尺寸,DEMO 确实也没有适配上,不知道是 ROM 的问题还是 App 的问题,有待后续的进一步研究

当然 12 以前的系统想要支持圆角设计也很简单: 自定义 radius 的 attribute,应用在shape drawable 上,手动将 drawable 应用到 background。具体可参考官方 Sample:

https://github.com/android/user-interface-samples/tree/main/AppWidget

3. 动态的色彩效果

给小组件添加暗黑主题支持即可自动适配动态色彩。

@color/purple_500 @color/purple_700 @color/white ... @color/purple_200 @color/purple_700 @color/black ...

4. 改进的小组件预览

12 针对小组件选择时的预览界面进行了改进,方便展示更加精准的预览效果。

4.1 动态预览

之前只能使用 previewImage 属性展示一张预览图,功能迭代的过程中忘记更新它的话,可能导致预览和实际效果发生偏差。

12 新引入了 previewLayout 属性用以配置小组件的实际布局,使得用户能够在小组件的选择器里看到更加接近实际效果的视图,而不再是一层不变的静态图片。

这样一来在保证效果一致的同时免去了额外维护预览图的麻烦。

android:previewImage="@drawable/app_widget_pedometer_preview_2" android:previewLayout="@layout/widget_pedometer" smallView SizeF(100f, 200f) -> tallView SizeF(200f, 100f) -> wideView ... } }

注意: 实际上 Size 列表由 Launcher 提供,如果 3rd Launcher 没有适配这一特性的话,回传的 Size 可能为空。

8. 自由地更新视图

RemoteViews 作为小组件视图的重要管理类,本次 OSV 也添加了诸多 API,以便更加自由地控制视图的展示。

更改颜色的 setColorStateList()

更改边距的 setViewLayoutMargin()

更改宽高的 setViewLayoutWidth() 等

这些新 API 可以助力我们实很多方便的功能,比如 CheckBox 选中之后更新文本颜色,思路很简单:

监听小组件的点击事件并传递目标视图

根据 CheckBox 的状态获得预设的文本颜色

使用 setColorStateList() 更新

override fun onReceive(context: Context?, intent: Intent?) { ... // Get target widget. val appWidgetManager = AppWidgetManager.getInstance(context) val thisAppWidget = ComponentName(context!!.packageName, TodoListAppWidget::class.java.name) val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget) // Update widget color parameters dynamically. for (appWidgetId in appWidgetIds) { val remoteViews = RemoteViews(context.packageName, R.layout.widget_todo_list) remoteViews.setColorStateList( viewId, "setTextColor", getColorStateList(context, checked) ) appWidgetManager.updateAppWidget(appWidgetId, remoteViews) } } private fun getColorStateList(context: Context, checkStatus: Boolean): ColorStateList = if (checkStatus) ColorStateList.valueOf(context.getColor(R.color.widget_checked_text_color)) else ColorStateList.valueOf(context.getColor(R.color.widget_unchecked_text_color))

再比如 Chart 线图太小,看不清楚。可以让它在点击之后放大,再点击之后恢复原样。

// 根据记录的缩放状态获得预设的宽高 // 通过setViewLayoutWidth和setViewLayoutHeight更新宽高 override fun onReceive(context: Context?, intent: Intent?) { ... val widthScaleSize = if (scaleOutStatus) 200f else 260f val heightScaleSize = if (scaleOutStatus) 130f else 160f // Update widget layout parameters dynamically. for (appWidgetId in appWidgetIds) { val remoteViews = RemoteViews(context.packageName, R.layout.widget_pedometer) remoteViews.setViewLayoutWidth(viewId, widthScaleSize, TypedValue.COMPLEX_UNIT_DIP) remoteViews.setViewLayoutHeight(viewId, heightScaleSize, TypedValue.COMPLEX_UNIT_DIP) appWidgetManager.updateAppWidget(appWidgetId, remoteViews) } }

9. 流畅的启动效果

12 版本上点击 Widget 启动 App 的时候可以呈现更流畅的过渡效果,适配也很简单。官方指示只需给小组件的根布局指定 android 的 backgoround id 即可。

实际的动作显示添加这个 ID 后 App 启动没有什么变化,个中原因需要继续研究。

12 开始对从 Broadcast Receiver 或 Serivce 启动 Activity 做了更严格的限制,但不包括 Widget 发起的场合。但为了避免视觉上的突兀,这种后台启动的情况下不展示迁移动画。

10. 简化的数据绑定

小组件里展示 ListView 的需求也很常见,提供数据的话需要声明一个 RemoteViewsService 以返回 RemoteViewsFactory,比较绕。

而 12 里新增的 setRemoteAdapter (int , RemoteCollectionItems) API 则可以大大简化这个绑定过程。

比如制作一个即将到来的事件列表小组件,通过这个 API 便可以高效注入数据。

private fun updateCountDownList(...) { ... // 创建用于构建Remote集合数据的Builder val builder = RemoteViews.RemoteCollectionItems.Builder() val menuResources = context.resources.obtainTypedArray(R.array.count_down_list_titles) // 往Builder里添加各Item对应的RemoteViews for (index in 0 until menuResources.length()) { ... builder.addItem(index.toLong(), constructRemoteViews(context, resId)) } // 构建Remote集合数据 // 并通过setRemoteAdapter直接放入到ListView里 val collectionItems = builder.setHasStableIds(true).build() remoteViews.setRemoteAdapter(R.id.count_down_list, collectionItems) ... } // 创建ListView各Item对应的RemoteViews private fun constructRemoteViews(...): RemoteViews { val remoteViews = RemoteViews(context.packageName, R.layout.item_count_down) val itemData = context.resources.getStringArray(stringArrayId) // 遍历Item数据行设置对应的文本 itemData.forEachIndexed { index, value -> val viewId = when (index) { 0 -> R.id.item_title 1 -> R.id.item_time ... } remoteViews.setTextViewText(viewId, value) } return remoteViews }

如果 Item 的布局不固定不止一种,可以使用 setViewTypeCount 指定布局类型的数目,告知 ListView 需要提供的 ViewHolder 种类。如果不指定也可以,系统将自动识别布局的种类,需要系统额外处理而已。

但要注意: 如果指定的数目和实际的不一致会引发异常。

IllegalArgumentException: View type count is set to 2, but the collection contains 3 different layout ids

另外,需要补充一下,支持该 API 的 View 必须是 AdapterView 的子类,比如常见的ListView、GridView 等。RecyclerView 是不支持的,毕竟小组件里数据量不多,不能使用也没关系。

11. 新增 API 总结

简要罗列一下 12 针对小组件新增的 API,方便大家查阅。

11.1 RemoteViews 类

方法

作用RemoteViews(Map)根据响应式布局映射表创建目标 RemoteViewsaddStableView()向 RemoteViews 动态添加子 View,类似 ViewGroup#addView()setCompoundButtonChecked()针对 CheckBox 或 Switch 控件更新选中状态setRadioGroupChecked()针对 RadioButton 控件更新选中状态setRemoteAdapter(int , RemoteCollectionItems)直接将数据填充进小组件的 ListViewsetColorStateList()动态更新小组件视图的颜色setViewLayoutMargin()动态更新小组件视图的边距setViewLayoutWidth()、setViewLayoutHeight()动态更新小组件视图的宽高setOnCheckedChangeResponse()监听 CheckBox 等三种状态小组件的状态变化

11.2 XML 属性

属性作用description配置小组件在选择器里的补充描述previewLayout配置小组件的预览布局reconfigurable指定小组件的尺寸支持直接调节configuration_optional指定小组件的内容可以采用默认设计,无需启动配置画面targetCellWidth、targetCellHeight限定小组件所占的 Launcher 单元格maxResizeWidth、maxResizeHeight配置小组件所能支持的最大高宽尺寸

结语

通过上面的解读,大家可以感受到 Google 在小组件的重新设计上耗费了诸多努力,它给这个老旧的功能注入很多新玩法和新花样。

简要回顾一下 Android 12 里小组件的新特性:

更便捷的小组件选择器

更美观的圆角边框设计

更灵活的小组件预览

更完整的控件支持

更方便的尺寸调节

更精准的布局控制

更自由的视图更新

更简便的列表数据绑定

如此之多的新特性,在助力小组件高效开发的同时,还能给用户呈现更加优秀的使用体验。

跟随 Android 12 的脚步,快快尝试起来,让现有的小组件重新绽放光彩。

未决事项

1. 小组件内部视图的圆角尺寸如何适配?

2. 小组件启动 App 的流畅过渡效果如何实现,是什么效果?

本文 DEMO

https://github.com/ellisonchan/NewAppWidget

参考资料

https://zhuanlan.zhihu.com/p/373609438

https://developer.android.google.cn/about/versions/12/features/widgets

https://github.com/android/user-interface-samples/tree/main/AppWidget

长按右侧二维码

查看更多开发者精彩分享

"开发者说·DTalk" 面向中国开发者们征集 Google 移动应用 (apps & games) 相关的产品/技术内容。欢迎大家前来分享您对移动应用的行业洞察或见解、移动开发过程中的心得或新发现、以及应用出海的实战经验总结和相关产品的使用反馈等。我们由衷地希望可以给这些出众的中国开发者们提供更好展现自己、充分发挥自己特长的平台。我们将通过大家的技术内容着重选出优秀案例进行谷歌开发技术专家 (GDE) 的推荐。

 点击屏末 | 阅读原文 | 即刻报名参与 "开发者说·DTalk" 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3