由于在iOS14中推出的小组件的功用,让咱们重新开端关注起小组件了。虽然安卓是很久之前就有了小组件的功用,可是由于它的不美观和不实用,以及对开发者也不够友爱,逐步变成为抛弃的状况。
直到Android12,再一次更新了小组件的的相关功用,而且为了削减开发者的负担而推出了Jetpack Glance库。该库是根据Compose,是开发者运用Compose的指令快速上手进而削减开发成本。
那让咱们开端探求一下Glance吧。
1. 加上库的依靠
把下面的依靠信息添加到app的build.gralde文件中。
dependencies {
implementation("androidx.glance:glance:1.0.0-alpha01")
}
android {
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.1.0-beta03"
}
kotlinOptions {
jvmTarget = "1.8"
}
}
2. 承继GlanceAppWidget类
咱们需求承继GlanceAppWidget类然后重写Content办法。
class GlanceWidget : GlanceAppWidget(){
@Composable
override fun Content() {
// write compose ui code here
}
}
在Content办法内写咱们已经很熟悉的Compose UI语句就可以了。
可是这儿有一点需求分外的注意。咱们在运用Compose UI组件时需求运用glance的供给UI组件。 而不是Compose Material的UI组件。
组件的详细途径如下:(以Text为举例)
Glance供给的Compose UI组件: androidx.glance.text.Text
Compose Material供给的Compose UI组件:androidx.compose.material.Text
Glance供给的所有Compose UI组件列表如下:
Box, Column, Row, Text, Image, Button, LazyColumn, Spacer.
简略说明一下,为什么这儿需求运用的是Glance供给的组件而不是Compose Material的。
由于Glance的底层还是通过构建RemoteViews来完成小组件的显现。所以咱们只能运用Glance供给的UI组件,然后让Glance帮咱们把写好的UI代码转换成RemoveViews。

不可是需求运用Glance供给的Compose UI组件,为ui组件设置modifier的时候咱们也不能运用普通的modifier,而是需求运用Glance供给的GlanceModifier。
3. 小组件布局的自适应
运用Glance,咱们可认为小组件设置不同巨细的布局来完成用户在自由的调理组件巨细时显现不同的界面。
为了完成小组件布局的自适应,咱们首要要设置详细的布局巨细。咱们要重写sizeMode变量,在这儿规定小组件都有哪些巨细的布局。
private val SMALL_BOX = DpSize(90.dp, 90.dp)
private val BIG_BOX = DpSize(180.dp, 180.dp)
private val VERY_BIG_BOX = DpSize(300.dp, 300.dp)
private val ROW = DpSize(180.dp, 48.dp)
private val LARGE_ROW = DpSize(300.dp, 48.dp)
private val COLUMN = DpSize(48.dp, 180.dp)
private val LARGE_COLUMN = DpSize(48.dp, 300.dp)
override val sizeMode = SizeMode.Responsive(
setOf(SMALL_BOX, BIG_BOX, ROW, LARGE_ROW, COLUMN, LARGE_COLUMN)
)
然后,咱们在Content()中调用 LocalSize.current来检查当前组件的巨细,根据当前组件的巨细显现不同的布局。详细代码如下:
@Composable
override fun Content() {
val list = listOf(ACTION_ACTIVITY, ACTION_SERVICE, ACTION_BROADCAST, ACTION_CALLBACK)
when (LocalSize.current) {
SMALL_BOX, BIG_BOX, VERY_BIG_BOX -> {
WidgetBoxView(list)
}
ROW, LARGE_ROW -> {
WidgetRowView(list)
}
COLUMN, LARGE_COLUMN -> {
WidgetColumnView(list)
}
}
}
相关的UI代码如下。
@Composable
fun WidgetRowView(
list: List<String>
) {
Row(
modifier = GlanceModifier
.fillMaxSize()
.cornerRadius(24.dp)
.background(Color(0xfff1f1f1)),
horizontalAlignment = Alignment.Horizontal.CenterHorizontally,
verticalAlignment = Alignment.CenterVertically
) {
list.forEach { str ->
Button(
text = str,
onClick = getAction(str, LocalContext.current)
)
}
}
}
4. 设置GlanceAppWidgetReceiver
咱们需求承继GlanceAppWidgetReceiver类。然后重写glanceAppWidget变量的get办法。
在get办法中回来上面说到的承继自GlanceAppWidget的你创建的类。
在我这个例子中是回来GlanceWidget()。
需求这一步的原因是让App和Glance小组件进行衔接。
详细代码如下。
class GlanceReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget
get() = GlanceWidget()
}
5. 设置actions
开发者可以运用Glance供给的如下办法来调用Broadcast, Service, Activity和Callback。
- actionStartBroadcast
- actionStartService
- actionStartActivity
- actionRunCallback
在这儿我只展示怎么完成Callback的调用,关于其他的办法的调用请检查我的GitHub。
首要,咱们需求创建一个类且承继ActionCallback, 然后重写onRun办法。
class GlanceCallbackAction : ActionCallback {
override suspend fun onRun(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
Handler(context.mainLooper).post() {
val parameter = parameters[GlanceWidget.ACTION_PARAMETERS_KEY]
Toast.makeText(context, "GlanceClickAction, parameter: $parameter", Toast.LENGTH_LONG)
.show()
}
}
}
之后,咱们需求在按钮的clickable中去完成调用ActionCallback的代码。如果想要传递参数,需求运用actionParametersOf参数。actionParameter本质上是HashMap, 所以需求以Key和Value的方式放入需求传递的参数。详细代码如下:
actionRunCallback(
GlanceCallbackAction::class.java,
parameters = actionParametersOf(ACTION_PARAMETERS_KEY to str)
)
val ACTION_PARAMETERS_KEY = ActionParameters.Key<String>("parameters_keys")
6. 在AndroidManifest文件中设置相关信息
咱们不但要为上面的说到的service, broadcast等相关组件添加信息,还要把在小题目4中说到的GlanceAppWidgetReceiver的信息添加到AndroidManifest.xml文件中。
<manifest>
<application>
......
<receiver
android:name=".GlanceReceiver"
android:enabled="@bool/glance_appwidget_available"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<!-- 小部件装备信息 -->
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/glance_info" />
</receiver>
<receiver
android:name=".GlanceBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.hyejeanmoon.glancedemo" />
</intent-filter>
</receiver>
<service android:name=".GlanceService" />
</application>
</manifest>
7. 设置小组件的元数据
小组件的元数据指的是小组件相关的装备信息。该信息最终是要设置在AndroidManifest文件中的receiver中的。
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/glance_info" />
xml/glacen_info的详细代码如下。
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="<http://schemas.android.com/apk/res/android>"
android:minWidth="180dp"
android:minHeight="50dp"
android:resizeMode="horizontal|vertical"
android:targetCellWidth="3"
android:targetCellHeight="1"
android:widgetCategory="home_screen" />
widgetCategory: 声明小组件应该显现在哪个界面中。一共有home_screen(主屏幕)和keyguard(锁屏界面)两种。可是锁屏界面只能是Android5一下才可以设置,所以现在基本上只能设置主屏幕了。
targetCellWidth, targetCellHeight: 在Android12中新加的特点,声明组件应该以怎样的长高来显现。
previewImage: 设置小组件的预览图片,该图片会显现在选择小组件时的界面中。
还有许多可以设置的特点,更多请检查:developer.android.com/guide/topic…
8. 其他
Glance Demo Github: github.com/HyejeanMOON…