前言

Jetpack Compose 是用于构建原生界面的「新款 Android 工具包」。2021 Google IO 大会上,Google宣布:「Jetpack Compose 1.0 即将面世」

作为Android未来新的UI开发标准,Compose 会为 Android 开发带来哪些变化呢?本文将带来Jetpack Compose的特点及其跟传统Android UI开发方式的分析:

  1. 基于Kotlin

  2. 声明式开发

  3. UI刷新机制

  4. 状态管理

  5. UI组件类型

  6. 实时预览

  7. 兼容性

  8. Jetpack Compose 与 Flutter的关系


基于Kotlin

现行的 Andoird 开发体系:Java + xml,但近年来 Google已经宣布Kotlin是Android开发的第一语言。Jetpack Compose这套声明式UI采用的底层DSL是Kotlin,即 你在使用Jetpack Compose开发UI时,实际上是使用Kotlin进行UI开发,「即 完全统一了Android开发语言。」


声明式开发

现行的 Andoird 视图体系属于传统的命令式开发方式:使用XML布局、通过 findViewById 获取控件的引用,命令式地更新状态、刷新UI。命令式UI开发的特点是:

  • UI可变:接受命令后通过变化自身刷新UI

  • UI持有状态State:控件的变化通过改变自身状态实现

Jetpack Compose使用的是声明式UI开发方式,其特点相对于命令式UI开发有较大区别:

  • UI不可变 : @Composable函数不返回任何可引用句柄,无法被外界改变;

  • UI不持有State: @Composable函数无法持有状态,显示的数据都需要通过参数传入;

总的来说,Jetpack Compose进行声明式UI开发时:

  1. 每个UI绘制会一个“纯函数”的方式运行;

  2. 当 状态State 变化时函数重新执行刷新UI。


UI刷新机制

Jetpack Compose刷新UI的方式叫重组,即使用新数据再次调用UI绘制的函数。

@Composable
fun ClickCounter(clicks: Int, onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("I've been clicked $clicks times")
    }
}

如上述按钮设置:每次点击该按钮时,调用方都会更新 clicks 的值。Compose 会再次调用 lambda 与 Text 函数以显示新值。

当数据变化时就会触发重组,如果每次都全量重组则会带来很多性能损耗。「类似React那种声明式UI, 每次绘制时都会通过diff算法精准更新 DOM从而实现局部刷新,最终保证React的刷新性能。」

Jetpack Compose 为了保证重组性能才使用了类似的思想:「局部刷新,也叫智能重组」。原理是:在 Gap Buffer 这样线性结构上进行 diff。

「Gap Buffer 是一个树形结构经 DFS 处理后的数组」,数组单元通过 key 标记其在树上的位置信息。Compose 在编译期为Composable 生成带有位置信息的 key存入到 Gap Buffer 数组的对应位置。运行时根据 key 来识别 Composable 节点是否发生了位置变化,最终决定是否参与重组。同时,「Gap Buffer 还会记录 Composable 对象关联的状态(State 或 Parameters)」:仅当关联状态变化时,Composable 才会参与重组。


状态管理(State)

Jetpack Compose的UI变化本质是:「状态(State) 驱动」,即控件UI的变化原因是控件UI的状态发生了变化。

对于传统的UI开发模式,状态(State) 只是UI控件的一个属性,仅此而已。


UI组件类型

虽然Jetpack Compose 1.0 才刚面世,但实际上其UI组件库已经十分完备,几乎完全覆盖了Android现有视图系统的所有组件及能力,主要包括:

  • 基础UI组件,如Button、TextView等,连Card、Fab、AppBar等Material Designe的控件都会涵盖;

  • 列表类组件,如List等,采用items{...} 中创建每条项目的 Composalbe,避免了额外的Adapter适配;

  • 布局类组件,提供了多种容器类Composalbe,可以十分高效方便地对子组件进行布局;通过一系列链式调用的Modifier操作符来装饰 Composable 的外观。操作符的使用十分丰富,如size、backgrounds、padding等;

  • 动画组件,同样是采用状态(State)驱动进行动画效果的实现。


实时预览

Jetpack Compose 能做到开发过程中的「实时预览」,预览机制可以做到与真机无异,真正的所见所即得。


兼容性

Jetpack Compose 可以与Android现有的视图View开发体系一起兼容使用,即不一定是新有项目才使用Compose,「而是可以对已有项目引入Compose。」


Jetpack Compose 与 Flutter的关系

同属于UI开发框架,二者都是采用「声明式UI开发」,但二者并不存在互斥或者竞争关系。

因为:「Jetpack Compose存在于Android的原生UI绘制体系、Flutter主要还是应用于跨平台的UI绘制范畴内。」

但二者都是代表未来Android UI绘制的开发方向:「声明式UI开发」


展望

  • 正式发布:Compose 1.0 会在今年的7月正式发布,同时后续Android Studio 也将同步支持 Compose 开发。

  • 功能库支持越来越丰富:越来越多的 Jetpack 官方库以及常用的三方库开始加入对 Compose 的支持

  • 生态完善:Jetpack Compose目前不仅应用于Android客户端,同时最近也有Compose-Desktop、Compose-Web 等项目的发布,为 Compose 提供跨平台的能力,完善了整个Jetpack Compose的UI应用生态。


学习指南

1. 官方学习资料

https://goo.gle/compose-pathway https://goo.gle/compose-samples https://goo.gle/compose-docs

2. 中文学习项目

https://docs.compose.net.cn/


Jetpack Compose 1.0 终于要投入使用了!的更多相关文章

  1. Jetpack Compose What and Why, 6个问题

    Jetpack Compose What and Why, 6个问题 1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题. Jetpack Compose是什么? 它是一个声明 ...

  2. Jetpack Compose学习(1)——从登录页开始入门

    原文地址:Jetpack Compose学习(1)--从登录页开始入门 | Stars-One的杂货小窝 Jetpack Compose UI在前几天出了1.0正式版,之前一直还在观望,终于是出了正式 ...

  3. Jetpack Compose和View的互操作性

    Jetpack Compose Interoperability Compose风这么大, 对于已有项目使用新技术, 难免会担心兼容性. 对于Compose来说, 至少和View的结合是无缝的. (目 ...

  4. Android Kotlin Jetpack Compose UI框架 完全解析

    前言 Q1的时候公司列了个培训计划,部分人作为讲师要上报培训课题.那时候刚从好几个Android项目里抽离出来,正好看到Jetpack发布了新玩意儿--Compose,我被它的快速实时打包给吸引住了, ...

  5. Android全新UI编程 - Jetpack Compose 超详细教程

    1. 简介 Jetpack Compose是在2019Google i/O大会上发布的新的库.Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速 ...

  6. Jetpack Compose学习(2)——文本(Text)的使用

    原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...

  7. Jetpack Compose之隐藏Scaffold的BottomNavigation

    做主页导航时会用到底部导航栏,Jetpack Compose提供了基础槽位的布局Scaffold,使用Scaffold可以构建底部导航栏,例如: @Composable fun Greeting(vm ...

  8. Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用

    原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...

  9. Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用

    原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...

随机推荐

  1. unity中的文件存储路径与各平台(Android,iOS)的关系

    原文链接:unity中的文件存储路径与各平台(Android,iOS)的关系 主要是这个问题困扰我了一阵子,所以特写写... unity中的的各种存储方法的对应关系(直接上截图吧) 重点说的是Appl ...

  2. POJ 1703 Find them, Catch them 并查集,还是有点不理解

    题目不难理解,A判断2人是否属于同一帮派,D确认两人属于不同帮派.于是需要一个数组r[]来判断父亲节点和子节点的关系.具体思路可参考http://blog.csdn.net/freezhanacmor ...

  3. SpringBoot:SpringBoot中@Value注入失败

    1. 第一步检测语法是否正确 @Value("${test}") private String test; 2.第二步检测配置文件中是否有进行配置 url=testusername ...

  4. Java读取文件创建时间和最后修改时间

    import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.Input ...

  5. HDU2050

    思路分析,被我写到分割问题里面.可以去看看. 贴下代码

  6. Windows软件包管理工具:Scoop

    前言 删库跑路后,Windows系统如何快速安装应用程序,部署环境呢? 以前想过这个问题,最近在安装Hugo时发现使用软件包管理工具可以解决这个问题. 阅读建议 首先需要测试下载速度,尝试从官网下载, ...

  7. 「AGC023D」 Go Home

    「AGC023D」 Go Home 传送门 神题. 首先我们可以倒着考虑. 当车到达最后一栋楼的时候,车上一定只有到这栋楼的员工. 当车到达倒数第二栋楼的时候,车上一定只有到达剩下两栋楼的员工. 设这 ...

  8. C语言:监听键盘

    所谓键盘监听,就是用户按下某个键时系统做出相应的处理,本章讲到的输入输出函数也是键盘监听函数的一种,例如 getchar().getche().getch() 等.下面的代码演示了 getche() ...

  9. python_字典列表嵌套的排序问题

    上一篇我们聊到python 字典和列表嵌套用法,这次我们聊聊字典和列表嵌套中的排序问题,这个在python基础中不会提到,但实际经常运用,面试中也喜欢问,我们娓娓道来. 在说组合排序之前,先来看看排序 ...

  10. Linux系统下Java 转换Word到PDF时,结果文档内容乱码的解决方法

    本文分享在Linux系统下,通过Java 程序代码将Word转为PDF文档时,结果文档内容出现乱码该如何解决.具体可参考如下内容: 1.问题出现的背景 在Windows系统中,使用Spire.Doc ...