首页 > 其他分享 >Jetpack架构组件学习(6)——使用Glance实现桌面小组件

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

时间:2025-01-22 15:32:11浏览次数:1  
标签:widget Jetpack Image GlanceModifier 组件 Glance modifier glance dp

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

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

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

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

基本使用

1.添加依赖

添加Glance依赖:

// 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"

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-data
		android: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)

参考

标签:widget,Jetpack,Image,GlanceModifier,组件,Glance,modifier,glance,dp
From: https://www.cnblogs.com/stars-one/p/18686180

相关文章

  • 【vue3组件】【大文件上传】【断点续传】支持文件分块上传,能够在上传过程中暂停、继续
    一、概述本示例实现了一个基于Vue3和TypeScript的断点上传功能。该功能支持文件分块上传,能够在上传过程中暂停、继续上传,并且支持检测已经上传的分块,避免重复上传,提升上传效率。以下是关键的技术点与实现流程:文件分块:将大文件分成多个小块,每块的大小是固定的(例如5MB)......
  • 小程序中 button 和 image 组件的基本用法
    目录小程序中button和image组件的基本用法一、button组件(一)基本属性(二)事件绑定二、image组件(一)基本属性(二)图片加载优化在小程序开发中,button和image组件是常用的元素,它们能为用户界面增添交互性和丰富的视觉效果。以下将详细介绍这两个组件的基本用法,并附......
  • 【虚拟机】VMware Tools 13.0.0 发布 : 虚拟机必备组件 (驱动和交互式服务)
    VMware客户机操作系统无缝交互必备组件请访问原文链接:https://sysin.org/blog/vmware-tools-13/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgVMwareTools是一套安装在虚拟机的操作系统中的实用程序。VMwareTools可提高虚拟机的性能,并在VMware产品中实现主机......
  • Text组件的主要功能
    文章目录1概念介绍2使用方法3示例代码我们在上一章回中介绍了页面之间传递数据相关的内容,本章回中将介绍如何使用TextWidget。闲话休提,让我们一起TalkFlutter吧。1概念介绍我们在这里说的TextWidget就是显示文字内容的组件,其实我们一直在使用它,只是没有详......
  • Android JecPack组件之LifeCycles 使用详解
    一、背景LifeCycle是一个可以感知宿主生命周期变化的组件。常见的宿主包括Activity/Fragment、Service和Application。LifeCycle会持有宿主的生命周期状态的信息,当宿主生命周期发生变化时,会通知监听宿主的观察者。LifeCycle的出现主要是为了解决:系统组件的生命周期与......
  • 咱们继续学Java——高级篇 第一百八十三篇:之Java高级Swing编程之JEditorPane组件与进
    咱们继续学Java——高级篇第一百八十三篇:之Java高级Swing编程之JEditorPane组件与进度指示器在Java编程的学习旅程中,我们始终保持着积极探索、共同成长的态度。今天,我们将深入学习Java高级Swing编程中关于JEditorPane组件与进度指示器的部分,包括JEditorPane组件的功能特性......
  • 存根组件 是什么?
    存根组件(StubComponents)是单元测试中的一个重要概念,特别是在使用Vue.js进行组件测试时。存根组件用于替代真实组件,通常是为了隔离被测组件的依赖,或者是为了加速测试执行速度。通过使用存根组件,你可以专注于测试当前组件的行为,而不必关心其子组件的具体实现。为什么需要存根组......
  • 深入探索 Vue.js 最新组件开发技术:实现动态模块加载器
    随着前端技术的飞速发展,Vue.js的组件化开发理念已经被广泛应用。今天,我们将探索一种最新的技术模式:动态模块加载器在Vue.js中的实现。这种模式可以提升应用的性能,并简化大型项目的组件管理。为什么需要动态模块加载器?在传统的Vue.js开发中,我们经常通过import和requir......
  • Vue.js 组件开发:构建可复用的UI元素
    ......
  • k8s的五大组件
    Kubernetes核心组件及其功能Kubernetes(K8s)是一个强大的容器编排平台,能够自动化容器化应用程序的部署、扩展和管理。其架构由多个组件协作完成,以下是Kubernetes的五大核心组件及其功能。1.APIServer(kube-apiserver)作用:Kubernetes的所有请求都会通过APIServer,它是集......