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

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

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里进行了重新设计、重新出发。

1832b220aa754cd18c504acc7686a560.png

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

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

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

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

1832b220aa754cd18c504acc7686a560.png

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


选择器

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

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

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

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

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

image.png

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上,就能有圆角效果。

1832b220aa754cd18c504acc7686a560.png

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


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

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

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


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

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

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

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

1672150735802.png

注意:


这些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. 动态的色彩效果

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

<!-- values/themes.xml -->
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.AppWidget" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        ...
    </style>
</resources>
<!-- values-night/themes.xml -->
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.AppWidget" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimary">@color/purple_200</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/black</item>
        ...
    </style>
</resources>

image.gif

4. 改进的小组件预览

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

4.1 动态预览

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


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


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

<appwidget-provider
    <!-- 既存的图片属性指定UI提供的设计图 -->
    android:previewImage="@drawable/app_widget_pedometer_preview_2"
    <!-- 新的预览API里指定实际的布局 -->
    android:previewLayout="@layout/widget_pedometer"
</appwidget-provider>

左边是步数小组件一开始的设计图,右边是最后的实际效果。

1832b220aa754cd18c504acc7686a560.png

如果忘记说服UI重新作图的话,在11上的预览图会和实际效果有较大偏差。而12上不用在乎设计图是否更新,借助新的API即可直接预览实际效果,所见即所得。

1832b220aa754cd18c504acc7686a560.png

一般来说previewLayout属性最好指定小组件的实际布局。但如果预览的测试数据和实际的默认值有冲突的话,可以指定专用的预览布局,只需要确保布局的一致。

4.2 添加预览说明

description属性则可以在小组件预览的下方展示额外的说明,便于用户更好地了解其功能定位。

<appwidget-provider
    android:description="@string/app_widget_pedometer_description">
</appwidget-provider>

1832b220aa754cd18c504acc7686a560.png

需要提醒的是description属性并非12新增,但12之前的选择器不支持展示这个说明。

5. 支持新的交互控件

之前的小组件不支持CheckBox等控件,从12开始全面支持CheckBoxSwitchRadioButton三种状态控件。

下面是采用这三种控件的简单效果。

b41705914ab149ed906428aa9032a946.gif

再做个简单的待办事项以更好地说明状态小组件的使用。

// 小组件件布局里指定CheckBox控件即可
<LinearLayout ...
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:theme="@style/Theme.AppWidget.AppWidgetContainer">
    <include layout="@layout/widget_todo_list_title_region" />
    <CheckBox
        android:id="@+id/checkbox_first"
        style="@style/Widget.AppWidget.Checkbox"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/todo_list_sample_1"
        Tools:text="@string/todo_list_tool" />
    ...
</LinearLayout>

1832b220aa754cd18c504acc7686a560.png

如果将同样的代码运行到11上,则会显示加载失败。


日志


AppWidgetHostView: Error inflating AppWidget AppWidgetProviderInfo(UserHandle{0}/ComponentInfo{com.example.splash/com.example.splash.widget.TodoListAppWidget}): android.view.InflateException:

Binary XML file line #13 in com.example.splash:layout/widget_todo_list: Binary XML file line #13 in com.example.splash:layout/widget_todo_list: Error inflating class android.widget.CheckBox

image.png

文本内容不确定的话,可以通过代码动态地控制文本,同时还可以监听用户的选择事件。

比如我们要展示Android开发者如今要学习的三座大山,选中的时候弹出Toast。

private fun updateAppWidget(...) {
    val viewId1 = R.id.checkbox_first
    val pendingIntent = PendingIntent.getBroadcast(...)
    val rv = RemoteViews(context.packageName, R.layout.widget_todo_list)
    rv.apply {
        // 设置文本
        setTextViewText(viewId1, context.resources.getString(R.string.todo_list_android))
        ...
        // 设置CheckBox的默认选中状态
        setCompoundButtonChecked(viewId1, true)
        // 监听相应的CheckBox的选中事件
        setOnCheckedChangeResponse(
            viewId1,
            RemoteViews.RemoteResponse.fromPendingIntent(pendingIntent)
        )
    }
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}
override fun onReceive(context: Context?, intent: Intent?) {
    ...
    val checked = intent.extras?.getBoolean(RemoteViews.EXTRA_CHECKED, false) ?: false
    val viewId = intent.extras?.getInt(EXTRA_VIEW_ID) ?: -1
    Toast.makeText(
        context,
        "ViewId : $viewId's checked status is now : $checked",
        Toast.LENGTH_SHORT
    ).show()
}

b41705914ab149ed906428aa9032a946.gif

相关文章
|
5月前
|
存储 设计模式 数据库
构建高效的安卓应用:探究Android Jetpack架构组件
【4月更文挑战第20天】 在移动开发的世界中,构建一个既高效又可维护的安卓应用是每个开发者追求的目标。随着Android Jetpack的推出,Google为开发者提供了一套高质量的库、工具和指南,以简化应用程序开发流程。本文将深入探讨Jetpack的核心组件之一——架构组件,并展示如何将其应用于实际项目中,以提升应用的响应性和稳定性。我们将通过分析这些组件的设计原则,以及它们如何协同工作,来揭示它们对于构建现代化安卓应用的重要性。
|
5月前
|
Android开发 算法 架构师
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
|
5月前
|
Android开发 缓存 双11
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
|
5天前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
|
18天前
|
存储 开发框架 数据可视化
深入解析Android应用开发中的四大核心组件
本文将探讨Android开发中的四大核心组件——Activity、Service、BroadcastReceiver和ContentProvider。我们将深入了解每个组件的定义、作用、使用方法及它们之间的交互方式,以帮助开发者更好地理解和应用这些组件,提升Android应用开发的能力和效率。
|
5月前
|
Java 开发工具 Android开发
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
46 4
|
1月前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。
|
2月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
2月前
|
XML 搜索推荐 Android开发
安卓开发中的自定义View组件实践
【8月更文挑战第30天】探索Android世界,自定义View是提升应用界面的关键。本文以简洁的语言带你了解如何创建自定义View,从基础到高级技巧,一步步打造个性化的UI组件。
|
2月前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
33 0