Jetpack架构组件学习(6)——使用Glance实现桌面小组件

news/2025/1/22 15:31:19/文章来源:https://www.cnblogs.com/stars-one/p/18686180

原文地址: Jetpack架构组件学习(6)——使用Glance实现桌面小组件-Stars-One的杂货小窝

公司陆续整了几个Compose写的app,有个小组件的功能,顺便试了下Jetpack库里的Glance框架

感觉与原来的Remoteview差点意思,不过点击事件的使用比Remoteview要方便不少

PS: 如果想看Remoteview实现的小组件,可以参考我的此文Android 桌面小组件使用-Stars-One的杂货小窝

基本使用

1.添加依赖

添加Glance依赖:

// For AppWidgets supportimplementation "androidx.glance:glance-appwidget:1.1.0"// For interop APIs with Material 3implementation "androidx.glance:glance-material3:1.1.0"// For interop APIs with Material 2implementation "androidx.glance:glance-material:1.1.0"

2.正常的相关设置

xml文件夹添加小组件widget_info.xml配置:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:targetCellWidth="2"android:targetCellHeight="2"android:minWidth="250dp"android:minHeight="250dp"android:updatePeriodMillis="0"android:initialLayout="@layout/glance_default_loading_layout"tools:targetApi="s">
</appwidget-provider>

清单文件配置:

<receiver android:name=".appwidgets.MyAppWidgetReceiver"android:exported="true"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/widget_info" />
</receiver>

3.创建widget对象和实现界面

需要注意的几点:

  1. 界面的Row,Column,Text等,注意要使用Glance的包下的,否则会无法正常显示界面

官方也是说明了,Row,Box,Column实际最后创建的对象对应的Linearlayout和Framelayout

  1. 点击跳转的对应actionStartActivity方法,实际是返回一个Action对象 通过GlanceModifier.clickable(actionStartActivity(MainActivity::class.java))进行对应跳转

除了activity外,还能启动Service,BoardCast,详见此文档处理用户互动 | Jetpack Compose | Android Developers

  1. 关于背景圆角的方法,目前采用Box里面套一个Image和具体内容实现,Image去加载我们drawable里的矢量图对象(shape的那种)来实现
  2. remember在里面可用,但如果结合animateColorAsState这种动画效果,实际上并没有效果(只是单纯的变更,没有中间过渡过程)
class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {//MyAppWidget里就是类似我们remoteview的创建override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
}class MyAppWidget : GlanceAppWidget() {override suspend fun provideGlance(context: Context, id: GlanceId) {// In this method, load data needed to render the AppWidget.// Use `withContext` to switch to another thread for long running// operations.provideContent {val upSpeed by DataRespotiy.upSpeed.asFlow().collectAsState(initial = 0L)val downloadSpeed by DataRespotiy.downloadSpeed.asFlow().collectAsState(initial = 0L)Box(GlanceModifier.fillMaxSize()) {Image(provider = ImageProvider(R.drawable.app_widget_bg), contentDescription = null, modifier = GlanceModifier.fillMaxSize())Column(GlanceModifier.fillMaxSize()) {Spacer(GlanceModifier.height(28.dp))Row(GlanceModifier.fillMaxWidth().padding(horizontal = 20.dp)) {androidx.glance.Image(provider = ImageProvider(R.mipmap.logo), contentDescription = null, modifier = GlanceModifier.size(108.dp))Spacer(modifier = GlanceModifier.width(24.dp))Column(GlanceModifier.defaultWeight()) {Row(modifier = GlanceModifier.wrapContentHeight(), horizontalAlignment = Alignment.End, verticalAlignment = Alignment.Vertical.CenterVertically) {Text(text = "${upSpeed} Kb/s", style = TextStyle(color = ColorProvider(APP_Primary_color), fontSize = 22.sp))Spacer(modifier = GlanceModifier.width(4.dp))androidx.glance.Image(provider = ImageProvider(R.drawable.icon_upload_widget), contentDescription = null, modifier = GlanceModifier.size(32.dp))}Spacer(modifier = GlanceModifier.height(18.dp))Row(modifier = GlanceModifier, horizontalAlignment = Alignment.End, verticalAlignment = Alignment.Vertical.CenterVertically) {Text(text = "${downloadSpeed} Kb/s", style = TextStyle(color = ColorProvider(APP_Bigfile_color), fontSize = 22.sp))Spacer(modifier = GlanceModifier.width(4.dp))androidx.glance.Image(provider = ImageProvider(R.drawable.icon_down_widget), contentDescription = null, modifier = GlanceModifier.size(32.dp))}}}Spacer(GlanceModifier.height(28.dp))Box(modifier = GlanceModifier.fillMaxWidth().defaultWeight()) {Image(provider = ImageProvider(R.drawable.app_widget_bg1), contentDescription = null, modifier = GlanceModifier.fillMaxSize())Row(modifier = GlanceModifier.fillMaxSize().padding(horizontal = 20.dp,16.dp), horizontalAlignment = Alignment.CenterHorizontally) {val modifier = GlanceModifier.defaultWeight()//todo 不同的item类型repeat(3) { index ->Row(modifier, horizontalAlignment = Alignment.CenterHorizontally, verticalAlignment = Alignment.Vertical.CenterVertically) {androidx.glance.Image(provider = ImageProvider(R.drawable.icon_net_test), contentDescription = null, modifier = GlanceModifier.size(108.dp).clickable(actionStartActivity(MainActivity::class.java)))}Spacer(GlanceModifier.width(20.dp))}}}}}}}
}

其他补充

更新小组件方法:

val manager = GlanceAppWidgetManager(application)
val widget = MyAppWidget()
val glanceIds = manager.getGlanceIds(widget.javaClass)glanceIds.forEach { glanceId ->widget.update(application, glanceId)
}//第二种方式(实际上和上面的方法是一样的,下面这个是官方给我们封装的另外个方法)
MyAppWidget().updateAll(application)

参考

  • Glance 设置 | Jetpack Compose | Android Developers

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873274.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《操作系统真象还原》第九章 线程(二) 多线程轮转调度

本文是对《操作系统真象还原》第九章(二)学习的笔记,欢迎大家一起交流第九章 线程(二) 多线程轮转调度 本文是对《操作系统真象还原》第九章(二)学习的笔记,欢迎大家一起交流,目前所有代码已托管至 fdx-xdf/MyTinyOS 。 上一节中成功创建了线程并运行,这一节要实现的…

Cisco APIC 6.0(8e)M - 应用策略基础设施控制器

Cisco APIC 6.0(8e)M - 应用策略基础设施控制器Cisco APIC 6.0(8e)M - 应用策略基础设施控制器 Application Policy Infrastructure Controller (APIC) 请访问原文链接:https://sysin.org/blog/cisco-apic-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org思科…

clickhouse本地表和分布式表说明(3分片单副本)

环境: clickhouse:24.8.11.51.创建本地表和分布式表 在一个节点上执行即可,我这里配置的分片使用了 defaultclickhouse-client --host 192.168.1.102 --port=9000 use db_test CREATE TABLE tb_test_local ON CLUSTER default (id Int32,name String,timestamp DateTime DEFAUL…

分发测试

协程的IO asyncio 作为实现异步编程的库,任务执行中遇到系统IO的时能够自动切换到其他任务。协程的IO asyncio 作为实现异步编程的库,任务执行中遇到系统IO的时能够自动切换到其他任务。协程使用的IO模型是IO多路复用。在 asyncio 低阶API 一篇中提到过 “以Linux系统为例,I…

【图】数场功能架构图

【图】数场功能架构图(来源:国家数据基础设施建设指引) (1)点:参与方之间的自身数据安全能力约定; (2)线:涉及到网络高可用,可以根据DSMM评估域进行统一约定; (3)面:DSMM中数据生存周期安全,场景化能力约定;

hyperledger

https://topgoer.cn/docs/blockchain_guide/blockchain_guide-1emut2dv80st1Hyperledger 所有项目代码托管在 Github上。目前,主要包括如下顶级项目(按时间顺序)。Fabric:包括 Fabric、Fabric CA、Fabric SDK(包括 Node.Js、Java、Python 和 Go 语言)等,目标是区块链的基…

【图】数联网功能架构图

【图】数联网功能架构图(来源:国家数据基础设施建设指引)

米尔瑞芯微第二代8nm高性能AIOT平台-RK3576开发板怎么样?

文章来源公众号:电子开发学习 瑞芯微近期推出了第二代8nm高性能AIOT平台——RK3576。 RK3576应用方向指向工业控制及网关,云终端,人脸识别设备,车载中控,商显等等。参数方面,内置了四核Cortex-A72+四核Cortex-A53,频率最高2.2GHz,内置ARM G52 MC3 GPU,NPU算力高达6TO…

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译我使用的是unbuntu20.04版本中,通过apt安装的openssl,发现openssl中的多个库文件中会出现类似DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)),导致引入头文件时无法编译成功. 例如bio.…

人工智能创新型教师培育计划(第一期)

Skip to contentOpenHydraSearchKMain Navigation首页 课程新一代人工智能经典实验【中学】 XEdu系列【中学】 中小学AI开源课程倡议使用指南活动获取支持On this page人工智能创新型教师培育计划(第一期) 一、组织单位 二、活动背景 三、活动内容 四、活动安排 五、师资介绍…

前置数学

一些必要 trick推式子,先提 \(\sum\) 和 \(\Pi\) 到最前面,然后从后往前合并,必要时考虑更改 \(\sum\) 的取值 看到次方变为斯特林数,\(x^n=\sum\limits_{i=0}^{n} {n \brace i}{x \choose i}i!=\sum\limits_{i=0}^{n}\sum\limits_{i=1}^m{(-1)^{m-i}\frac{i^n}{(m-i)!}}{x…

MUX-VLAN

MUX VLAN(Multiplex VLAN)是一种高级的VLAN技术,它通过在交换机上实现二层流量隔离和灵活的网络资源控制,提供了一种更为细致的网络管理方式。 一、基本概念 MUX VLAN分为主VLAN(Principal VLAN)和多个子VLAN(Subordinate VLAN)。 主VLAN是MUX VLAN配置中的核心VLAN,它…