Android Jetpack Compose开发小组件【入门篇】

开发环境:

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)),

                )
            }

注意,注意,注意包名的导入,完整包名在上面啊。

效果:

后续再将难度加大的,这是带入门篇的哈。

相关推荐
一个小白119 分钟前
C++——list模拟实现
开发语言·c++
bug总结19 分钟前
新学一个JavaScript 的 classList API
开发语言·javascript·ecmascript
小猫猫猫◍˃ᵕ˂◍20 分钟前
备忘录模式:快速恢复原始数据
android·java·备忘录模式
Nicole Potter26 分钟前
请说明C#中的List是如何扩容的?
开发语言·面试·c#
十八朵郁金香1 小时前
通俗易懂的DOM1级标准介绍
开发语言·前端·javascript
阿尔法波1 小时前
python与pycharm如何设置文件夹为源代码根目录
开发语言·python·pycharm
xing25161 小时前
pytest下allure
开发语言·python·pytest
眸笑丶1 小时前
使用 Python 调用 Ollama API 并调用 deepseek-r1:8b 模型
开发语言·python
enyp802 小时前
Qt QStackedWidget 总结
开发语言·qt
gu202 小时前
c#编程:学习Linq,重几个简单示例开始
开发语言·学习·c#·linq