KotlinConf’23
Amsterdam
Compose 玩点花
Zhujiang/朱江
01
02
03
04
Compose 简介
初体验之踩坑
初体验之绘制
初体验之打包
01
Compose 简介
Pseudo-intelligence, light intelligence,
缘起 Compose
从 Jetpack Compose 说起:Google 从 2017 年开始立项开搞 Compose 到第一个正式版本用了四年的时间,那么久的时间,投入了那么多的人力,以及后面投入了大量经费宣传,无一不在告诉安卓开发者 Compose 很重要,这也是之后安卓开发的新方向!所以当第一个 alpha 版本的 Compose 出现的时候我就坐不住了,立马加上依赖尝试了下!刚开始写的时候感觉有点奇怪,毕竟从之前的开发模式变为了全新的声明式开发,但写了不到一周就感受到了 Compose 的优势,编写起来太快了,动画实现起来也太简单了,声明式编程也太方便了。。。。
Lenovo
其实 Compose Desktop 出现的也很早,Jetpack Compose 出来没多久它也就出来了,有很多同行在 Compose Desktop 出来第一个 alpha 版本的时候就开始研究,不过由于我是做安卓开发的,日常工作也不会涉及到桌面开发,况且 Compose Desktop 是 Jetbrains 开发的,并不 Google 开发的,毕竟是模仿 Jetpack Compose 的,未来两边的 API 都有可能对应不上,所以也就一直没有关注。
Jetbrains Compose
公众号:《Android 开发者》在 2022 年 11 月 30 日早上发了一篇文章,名为:“Jetpack 更新一览 | 2022 Android 开发者峰会”,这篇文章的前半部分没有什么新鲜感,因为这些库我也一直在用,也经常关注着新版本和新功能,但看到文章最后的时候,里面有一段话是这么写的:
Lenovo
转折点
这话说的,你们一直在尝试,Jetpack Compose 正式版都出来快一年半了!Compose Desktop 正式版也都一年多了!这么久怎么连点信都没有。。。不过好在现在有信了!Google 这也算放出了几个信号,也不知道我的理解是否正确😂:
1、他们也一直在关注 Jetbrains 的 Compose Desktop;
2、目前已经有两个 Jetpack 的库支持了 Compose Desktop;
3、后续也会将更多的 Jetpack 中的库支持 Compose Desktop!
Flutter 现在已经比较成熟了,它最大的优势就是跨平台,Flutter 虽然宣称的是原生的性能,一套代码多端实现,但其实对于跨平台来说一套代码并不能完全实现需求,肯定需要各种适配,只不过看框架适配的好与坏,Compose Desktop 也是如此,但 Flutter 的性能也只是媲美原生,而 Compose 就是原生啊!Compose Desktop 其实并不是和 Flutter 抢饭碗,它只是告诉广大安卓开发:你们并不需要学习安卓之外的东西就能开发各种设备上的应用!这也是 Kotlin 的辉煌,我个人认为这也是 Jetbrains 公司开发 Compose Desktop 的初衷。
Lenovo
对标 Flutter?
02
初体验之踩坑
Pseudo-intelligence, light intelligence,
我本来还想着使用 Android Studio 来使用 Compose Desktop 来着,结果打开 Android Studio 新建项目一看并没有找到创建 Compose Desktop 的入口,后来想想也对,Android Studio 嘛!本来就是为了构建 Android 项目的,并不是为了构建别的东西,对吧!(内心独白:可能是我自己没找到)
Lenovo
创建项目
Lenovo
项目结构
Lenovo
第一次运行
OK,到现在位置初始项目中的内容大概都过了一遍,接下来运行看下效果吧!
那么问题又来了,怎么运行呢。。。之前咱们运行安卓项目的时候都是点击 Android Studio 上方运行,但现在看下:
没有了,灰着的!不用担心,不还有 main 函数呢嘛!直接运行 main 函数!
Lenovo
运行结果
Lenovo
显示图片
刚还想的可以好好使用 Compose 来编写桌面程序来着,可我刚想显示一张图片就发现了问题!怎么显示???
在 Jetpack Compose 中显示图片不叫事,直接使用 painterResource 将图片资源传进去就可以了,但在 Compose Desktop 中该怎么办呢?先来看下 Compose Desktop 中的 Image :
可以看到和 Jetpack Compose 中是一致的,不同的就是如何在 Compose Desktop 中构建 Painter 。
Lenovo
显示普通图片
先来看一种构建的方式吧:
当然可以在 resource 中创建不同的文件夹来存放不同的资源,图片也是一样的。
这块的 resourcePath 指的是图片的路径,这个路径是如何定义的呢?还记得上面创建完项目的初始结构么?里面有一个 resource 文件夹,这个文件夹就是根目录,比如 resource 文件夹中有一张图片“icon.png”,要构建这张图片的Painter 就可以使用如下代码:
Lenovo
显示普通图片
由于我将图片放到 resource 中的 image 文件夹中,所以这块的路径做了一些修改,再来看下图片的目录吧:
Lenovo
显示 SVG 图片
咱们现在在安卓中使用的图片大多改为了 SVG 格式的,体积又小且清晰,接下来按照相同的方式试一下,先放一张 SVG 格式的图片到刚才创建的 image 文件夹中:
Lenovo
显示 SVG 图片
Compose Desktop 为我们提供了一个叫 loadSvgPainter 的函数,专门用来处理 SVG 图片,接下来使用下看看:
Lenovo
柳暗花明
上面的一堆都是自己犯傻。。。其实 Compose Desktop 中也可以直接使用 painterResource 来构建图片。
Lenovo
网络图片
在安卓中加载网络图片一般都会使用 Glide ,但 Glide 是依赖于安卓的,所以无法在 Compose Desktop 中使用,不过也没有必要,下面来看下如何在 Compose Desktop 中使用网络图片吧:
Lenovo
Jetpack 库使用
刚才在上面提到了,我就是因为 Google 说 Jetpack 中的库之后会支持 Compose Desktop 才决定玩一玩 Compose Desktop 的,那肯定也要尝试使用下啊!
Google 目前只推出了两个库支持:Collection 和 DataStore ,Collection 目前使用不到,那就先来看看如何使用 DataStore 吧!
Lenovo
Jetpack 库使用
其实 DataStore 的使用方法和之前在安卓中没有什么区别,唯一的区别就是创建的时候,先来看下在安卓中是如何创建 DataStore 的吧:
这里用到了 Context ,这就是安卓中独有的,Java 中并没有啊,Kotlin 中也没有啊!那应该如何创建呢?
DataStore 早就为我们考虑到了,使用 PreferenceDataStoreFactory 中的 create 方法就可以创建 DataStore 了。这块需要说明下 System.getProperty("user.home") ,这个获取的是用户 home 的路径。这块文件的后缀名一定得是 preferences_pb ,如果不写或修改为别的就会报错。剩下的使用方法就和安卓中一摸一样了!
03
初体验之绘制
Pseudo-intelligence, light intelligence,
Lenovo
动画的使用
Lenovo
可见性动画
可见性动画在页面左边用到了,点击添加按钮出现搜索页面的时候就使用的是可见性动画,简单看下代码:
可以看到这块在进入的时候使用了 slideInHorizontally 动画,顾名思义,就是水平滑动展开,退出的时候使用了 slideOutHorizontally ,就是水平滑动退出。
Lenovo
重复动画
无限重复动画在左边展示天气信息的天气图标上用到了,这块的重复动画使用了两种,如果是晴天的话就修改 Modifier.rotate ,因为晴天是太阳,旋转的话好看一些,如果不是晴天的话旋转不好看,所以改为 Modifier.offset ,这样平移的话好看一些。来看下实现代码吧:
Lenovo
差异处理
对话框、浏览器、系统菜单、托盘、通知。。。。
Lenovo
差异处理
我录制了一个完整的显示系统菜单、托盘以及通知的 GIF ,大家来看下效果吧。
04
初体验之打包
Pseudo-intelligence, light intelligence,
Lenovo
打包
由于 Compose Desktop 不止可以运行在 Mac 中,还可以运行在 Windows 和 Linux 中,所以需要打多个包。那使用 Compose Desktop 应该如何打包呢?
插件中的基本配置单元是一个 application ,application 是什么呢?在第一篇文章中也提到了,就是在 build.gradle.kts 文件中的代码,咱们再来看下:
一个 application 定义了一组最终二进制文件的共享配置。换句话说,application DSL 允许将一堆文件连同 JDK 分发包打包成一组各种格式(.dmg、.deb、.msi、.exe等)的压缩二进制安装程序。
Lenovo
打包
是不是有点恍然大明白的感觉!直接点击 IntelliJ IDEA 右侧边栏的 Gradle ,就会出现这个侧边栏,然后点击 Task 中的 compose desktop 就会出现上面描述的那些任务。
Lenovo
ClassNotFoundException
Gradle 插件使用 jlink 通过仅包含必要的 JDK 模块来最小化可分发的大小。此时,Gradle 插件不会自动确定必要的 JDK 模块。未能提供必要的模块不会导致编译问题,但会导致在运行时出现 ClassNotFoundException 的错误。
如果在运行打包的应用程序或任务时遇到 ClassNotFoundException ,可以使用DSL 方法runDistributable 来配置包含额外的 JDK 模块,需要使用 modules 来配置。
如果安装包的大小不重要的话,可以使用 includeAllModulesDSL 属性简单地包括所有运行时模块作为替代。
Lenovo
指定包版本
由于可以打多种不同的包,也有可能需要区分不同的版本。
Lenovo
修改应用图标
Window 可组合项中可以设定 Icon ,但此 Icon 并非应用程序的图标!因为应用程序图标需要以特定于操作系统的格式提供:由于可以打多种不同的包,也有可能需要区分不同的版本。
Lenovo
注意
目前没有交叉编译支持,因此只能使用特定操作系统构建格式(例如,要构建.dmg 就必须使用 macOS)。默认情况下会跳过与当前操作系统不兼容的任务。
Share your feedback�to help us better understand your KotlinConf’23�Global experience!