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

                )
            }

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

效果:

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

相关推荐
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust