开发环境:
Mac OS 15.0.1
Android Studio Jellyfish | 2023.3.1 Patch 2
当前程序环境
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
compose true
}
kotlinOptions {
jvmTarget = '1.8'
}
composeOptions {
kotlinCompilerExtensionVersion '1.5.1'
}
废话不讲,直接开始上手【创建的程序要支持Compose和kotlin开发】。
官方使用Jetpack Compose小组件文档网址:https://android-dot-google-developers.gonglchuangl.net/develop/ui/compose/glance/setup?hl=zh-cn
第一步:导入依赖
官方说明需要的依赖
kotlin
dependencies {
// For Glance support
implementation "androidx.glance:glance:1.1.0"
// For AppWidgets support
implementation "androidx.glance:glance-appwidget:1.1.0"
// For interop APIs with Material 3
implementation "androidx.glance:glance-material3:1.1.0"
// For interop APIs with Material 2
implementation "androidx.glance:glance-material:1.1.0"
}
截止当前最新版依赖如下
kotlin
// Android conpose的小组件
// For Wear-Tiles support 这个是穿戴OS的
//implementation "androidx.glance:glance-wear-tiles:1.0.0-alpha05"
// For Glance support
implementation "androidx.glance:glance:1.1.1"
// For AppWidgets support
implementation "androidx.glance:glance-appwidget:1.1.1"
// For interop APIs with Material 3
implementation "androidx.glance:glance-material3:1.1.1"
// For interop APIs with Material 2
implementation "androidx.glance:glance-material:1.1.1"
以上二选一导入app/build.gradle中。
第二步:使用 Glance 创建应用 widget。
1.在清单文件【AndroidManifest.xml】中声明 你的AppWidget组件
kotlin
<!-- 你的小组件 -->
<application
......>
<receiver android:name=".widget.MyAppWidgetReceiver"
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/my_app_widget_info" />
</receiver>
</application>
说明:receiver android:name就是你开发的组件名,.widget.MyAppWidgetReceiver,其中.号之前就是包名,省略了而已,用完整的包名也行,比如:xxx.xxx.xxx...widget.MyAppWidgetReceiver,我取的名字随意,这个名字就是继承GlanceAppWidgetReceiver的名字,具体根据你程序定义就行【见名知义就行】。
添加 AppWidgetProviderInfo 元数据就是需要自己定义一个@xml/my_app_widget_info 文件。在res/xml/my_app_widget_info.xml定义:
内容如下:
kotlin
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout"
android:resizeMode="horizontal|vertical"
android:minWidth="70dp"
android:minHeight="70dp">
</appwidget-provider>
其中,resizeMode就是设置以支持用户手动调整大小,如果希望小部件支持手动调整大小,可以在AppWidgetProviderInfo中使用resizeMode属性。支持的选项包括horizontal(横向调整)、vertical(纵向调整)和horizontal|vertical(全方位调整),可选。
注意:android:minWidth="70dp"和android:minHeight="70dp"建议加上,官方给的代码是没得的。因为有的手机不加这个是不会出现小组件的,比如华为。具体大小根据开发来,一般来说,
1x1 格子 为 70dp 70dp
2x2 格子 为 140dp 140dp
3x2 格子 为 210dp 140dp
4x2 格子 为 280dp 140dp
4x4 格子 为 280dp 280dp
具体根据厂商的分辨率不同而不同。
这是里面具体的声明,根据需要写。
kotlin
<declare-styleable name="AppWidgetProviderInfo">
<!-- AppWidget最小宽度. -->
<attr name="minWidth"/>
<!-- AppWidget最小高度. -->
<attr name="minHeight"/>
<!-- AppWidget 可调整到的最小宽度. -->
<attr name="minResizeWidth" format="dimension"/>
<!-- AppWidget 可调整到的最小高度. -->
<attr name="minResizeHeight" format="dimension"/>
<!-- AppWidget 可调整到的最大宽度. -->
<attr name="maxResizeWidth" format="dimension"/>
<!-- AppWidget 可调整到的最大高度. -->
<attr name="maxResizeHeight" format="dimension"/>
<!-- AppWidget 的默认宽度,以启动器网格单元为单位. -->
<attr name="targetCellWidth" format="integer"/>
<!-- AppWidget 的默认高度,以启动器网格单元为单位。 -->
<attr name="targetCellHeight" format="integer"/>
<!--以毫秒为单位的更新周期,如果小部件将自行更新,则为 0. -->
<attr name="updatePeriodMillis" format="integer" />
<!-- A resource id of a layout. -->
<attr name="initialLayout" format="reference" />
<!-- A resource id of a layout. -->
<attr name="initialKeyguardLayout" format="reference" />
<!-- A class name in the AppWidget's package to be launched to configure.
If not supplied, then no activity will be launched. -->
<attr name="configure" format="string" />
<!-- A preview, in a drawable resource id, of what the AppWidget will look like after it's
configured.
If not supplied, the AppWidget's icon will be used. -->
<attr name="previewImage" format="reference" />
<!-- The layout resource id of a preview of what the AppWidget will look like after it's
configured.
Unlike previewImage, previewLayout can better showcase AppWidget in different locales,
system themes, display sizes & density etc.
If supplied, this will take precedence over the previewImage on supported widget hosts.
Otherwise, previewImage will be used. -->
<attr name="previewLayout" format="reference" />
<!-- The view id of the AppWidget subview which should be auto-advanced.
by the widget's host. -->
<attr name="autoAdvanceViewId" format="reference" />
<!-- Optional parameter which indicates if and how this widget can be
resized. Supports combined values using | operator. -->
<attr name="resizeMode" format="integer">
<flag name="none" value="0x0" />
<flag name="horizontal" value="0x1" />
<flag name="vertical" value="0x2" />
</attr>
<!-- Optional parameter which indicates where this widget can be shown,
ie. home screen, keyguard, search bar or any combination thereof.
Supports combined values using | operator. -->
<attr name="widgetCategory" format="integer">
<flag name="home_screen" value="0x1" />
<flag name="keyguard" value="0x2" />
<flag name="searchbox" value="0x4" />
</attr>
<!-- Flags indicating various features supported by the widget. These are hints to the
widget host, and do not actually change the behavior of the widget. -->
<attr name="widgetFeatures" format="integer">
<!-- The widget can be reconfigured anytime after it is bound -->
<flag name="reconfigurable" value="0x1" />
<!-- The widget is added directly by the app, and does not need to appear in
the global list of available widgets -->
<flag name="hide_from_picker" value="0x2" />
<!-- The widget provides a default configuration. The host may decide not to launch
the provided configuration activity. -->
<flag name="configuration_optional" value="0x4" />
</attr>
<!-- A resource identifier for a string containing a short description of the widget. -->
<attr name="description" />
</declare-styleable>
翻译太多,太浪费我时间了,大家自己翻译哈,我主重点说。
第三步:创建MyAppWidgetReceiver.kt文件。
kotlin
class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
}
接下来,创建MyAppWidget.kt文件。
kotlin
class MyAppWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
MyLogUtils.e("小组件测试")
Text("你好啊")
}
}
}
}
完结。
桌面长按,搜索,找到你的应用,效果【这个展示了可上下拖动的属性 android:resizeMode="horizontal|vertical"】:
大坑【同志们得注意GlanceAppWidget一些组件以及组件属性跟常规应用内开发的组件和组件属性的包是不同的,小组件的包名带androidx.glance.啥】。上述程序的包为:
kotlin
import android.content.Context
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.provideContent
import androidx.glance.background
import androidx.glance.layout.Box
import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.padding
import androidx.glance.layout.size
import androidx.glance.text.Text
import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
扩展【重点,重点,重点】
对上述Text进行改变这个组件的颜色,背景等操作
kotlin
Box(
modifier = GlanceModifier
.fillMaxSize()
.padding(16.dp)
.background(ColorProvider(Color.Green))
.size(100.dp)
) {
Text(
modifier = GlanceModifier
.background(Color.Red),
text = "你好啊",
style = TextStyle(ColorProvider(Color.White)),
)
}
注意,注意,注意包名的导入,完整包名在上面啊。
效果:
后续再将难度加大的,这是带入门篇的哈。