前言

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. Redis的事务不是原子性的

    1.事务的四大特性 原子性(Atomicity):化学中的原子指不可再分的基本微粒,数据库中原子性强调事务是一个不可分割的整体,事务开始后所有操作要么全部成功,要么全部失败,不可能停滞在中间某个环节. ...

  2. Linux中重要目录详解

    Linux重要目录详解 / 根目录,第一层目录,所有其他目录的根,一般根目录下只存放目录.包括:/bin, /boot, /dev, /etc, /home, /lib, /mnt, /opt, /p ...

  3. 第5章:资源编排(YAML)

    5.1 编写YAML注意事项 YAML 是一种简洁的非标记语言. 语法格式: 缩进表示层级关系 不支持制表符"tab"缩进,使用空格缩进 通常开头缩进 2 个空格 字符后缩进 1 ...

  4. 42、mysql数据库(函数)

    1.mysql中提供的内置函数: (1)数学函数: 1)ROUND(x,y): 返回参数x的四舍五入的有y位小数的值.x不可转换时返回0,x为null时返回null. 2)RAND(): 返回0到1内 ...

  5. layui table 表格上添加日期控件

    方法一: var tableInit = table.render({ elem: '#tbtxrz' , method: 'post' , data: jsonData , height: &quo ...

  6. 『无为则无心』Python序列 — 24、Python序列的推导式

    目录 1.列表推导式 (1)快速体验 (2)带if的列表推导式 (3)多个for循环实现列表推导式 2.字典推导式 (1)创建一个字典 (2)将两个列表合并为一个字典 (3)提取字典中目标数据 3.集 ...

  7. 【Python从入门到精通】(九)Python中字符串的各种骚操作你已经烂熟于心了么?

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 本文将重点介绍Python字符串的各种常用方法,字符串是实际开发中经常用到的,所有熟练的掌握它的各种用法显得尤为重要. 干货满满,建议收藏,欢迎大 ...

  8. redis-list实现

    Redis 数据结构---链表 Redis的list底层实现使用的不是数组而是链表的数据结构 叫listnode  是一个双向链表 ListNode{ Struct listNode *prev  / ...

  9. linux 开机自启动的两种方式

    方法 1 – 使用 rc.local sudo vi /etc/rc.local 在文件最后加上: sh /root/script.sh & 如果是 CentOS,我们修改的是文件 /etc/ ...

  10. Linux alias 或者 unalias 设置别名

    设置别名 查看别名:alias 设置别名: 临时设置: alias show='ls -al' 上述设置方法存在一个问题,即设置的命令别名只针对当前回话有效,一旦连接断开并重连之前设置的别名别不在有效 ...