前言

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. gRPC(3):拦截器

    在 gRPC 调用过程中,我们可以拦截 RPC 的执行,在 RPC 服务执行前或执行后运行一些自定义逻辑,这在某些场景下很有用,例如身份验证.日志等,我们可以在 RPC 服务执行前检查调用方的身份信息 ...

  2. Burning Bridges 求tarjan求割边

    Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 ...

  3. Java Set HashSet

    import java.util.HashSet; import java.util.Set; /** Set存储特点:数据无序.不可重复 Set接口的实现类: HashSet:Set接口的主要实现类 ...

  4. WebService:java配置类形式发布WebService接口及遇见的问题总结

    配置WebService前需要以下依赖jar包 #版本只供参考,具体看项目 <dependency> <grouId>org.apache.cxf</grouId> ...

  5. Zookeeper:Windows下Zookeeper启动zkServer.cmd闪退问题

    Zookeeper在Windows下启动只需要运行zkServer.cmd双击即可(需保证运行环境中正确安装了Java运行环境) 但是在有的时候会出现双击闪退的情况.针对闪退,可按照如下方法进行解决: ...

  6. mybatis中使用selectKey,返回结果一直是1

    转:https://www.cnblogs.com/caizhen/p/9186608.html mybatis中使用selectKey,返回结果一直是1,结合这个问题,笔记一下selectKey标签 ...

  7. SpringMVC(5)数据绑定-2

    在SpringMVC(4)数据绑定-1中我们介绍了如何用@RequestParam来绑定数据,下面我们来看一下其它几个数据绑定注解的使用方法. 1.@PathVariable 用来绑定URL模板变量值 ...

  8. python pyinsane应用

    import sys from PIL import Image try: import src.abstract as pyinsane except ImportError: import pyi ...

  9. PYTHON 连接SQL2008 导出到EXCEL

    #import pymssql from datetime import datetime import pyodbc import os current_dir = os.path.abspath( ...

  10. DEV-C++ 5.11格式化源代码设置

    下载STYLEAStyle_3.1_windows.zip解压缩,复制到C:\Program Files (x86)\Dev-Cpp\AStyle以管理员身份打开dev-c++软件"工具&q ...