6.Jetpack Compose
Jetpack Compose 是 Google 耗费五年倾力打造,用于构建 Android 原生界面的全新 UI 工具包。Android 诞生多年,UI 体系早已成熟,为什么这么要重造一个轮子?🤔
原因:
XML 布局冗长、繁琐:遇到复杂的布局,把屏幕竖过来都看不全
View 编程方式的嵌套会带来性能影响:不合理的布局导致测量性能翻倍
手动更新视图复杂、易错
声明性界面模型逐渐流行:这种方式可以简化 UI 的构建和更新步骤,仅执行必要的更改
其发展历程:
17 年立项
之后长达三年的内部调查和实验
20 年初 dev 版公开,年中 alpha 版推出
21 年初 beta 版发布
21 年 4 月全球挑战推广
21 年 7 月正式发布
6.1 Compose 挑战赛
去年上半年 Google 启动了为期四周的全球 Compose 挑战赛,提供了 500 多份乐高联名积木,十几部 Pixel 手机奖品,引发数万计Android开发者尝鲜,提交作品。
第一周的挑战做一个宠物领养 App,我花了一个周末做了个 LovePet 并拿到了这个飘洋过海的乐高积木,在推特上提交作品截图之后还有好多老外点赞,是很不错的体验。
后面的挑战还有定时器 App,复刻 App 设计作品,发挥想象做个天气 App 等
这些比赛内容其实涵盖了 Compose 所需要用到的大部分技术。Google 的大力推广也足见其决心和重视程度,日后必将成为Android平台上重要的UI编写方式,早日上车!💪
6.2 编程思想
我们通过一个展示 “Hello World” 文本的小例子,来直观感受一下 Compose 编程思想的明显差异。
- 传统的 UI 编程方式
我们再熟悉不过了。常见的操作是先定义一个 xml,然后通过 Activity 的 setContentView() 将 xml 放进去,之后就交给系统来加载。
<androidx.constraintlayout.widget.ConstraintLayout ...> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" ... /> </androidx.constraintlayout.widget.ConstraintLayout>
class MainActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... setContentView(R.layout.activity_main) } }
- Compose 编程方式
Compose UI 工具包则依赖 Composable
注解将展示 UI 的函数声明为可组合函数,Compose 编译器负责标记可组合函数内的组件,并进行展示。
布局的部分均需要放在该函数内交由 Compose 组合。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... setContent { SimpleComposable() } } @Composable fun SimpleComposable() { Text("Hello World") } }
6.3 进阶示例
来看一下下面这个简单的动态效果,并思考一下:如果采用传统的 View 编程方式来实现,你需要多少代码量?
采用传统的 View 方式,无非是如下的思路,布局加上逻辑少于 100 行代码不太容易实现:
布局:CardView + LinearLayout(ImageView + TextView)
代码:监听、展开和隐藏 TextView,并考虑阴影和淡出动画)
那如果采用 Compose 来实现呢?只需要 10 行即可。
Composable 函数组合圆角组件 Card + 垂直布局组件 Column
Column 嵌套图片组件 Image 和动画组件 AnimatedVisibility 包裹的文本组件 Text
Column 的 click 事件更新展开或隐藏的 state,进而触发 AnimatedVisibility 的重组,刷新 Text 的展示与否
@Composable fun JetpackCompose() { Card { var expanded by remember { mutableStateOf(false) } Column(Modifier.clickable { expanded = !expanded }) { Image(painterResource(R.drawable.jetpack_compose)) AnimatedVisibility(expanded) { Text( text = "Jetpack Compose", style = MaterialTheme.typographt.h2, ) } } } }
6.4 优势
篇幅有限,事实上 Compose 具备非常多的优势,亟待大家的挖掘:
声明式 UI:只负责描述界面,Compose 系统负责其余工作
状态驱动:界面随着状态自动更新
高效渲染:固定测量,层级嵌套性能仍是 O(n)
结合 AS 的 Preview 视图可实时查看和直接交互 UI
兼容传统 View 树编程方式,可混合使用
支持 Material Design 设计语言
拥有 Jetpack 框架的大力配合
基于 Kotlin,代码简洁,大量 Kotlin 专属 API
跨平台亦有布局:Desktop、 Web
大家可以利用 Compose 先来实现一个新画面,或者改造一个现有画面,逐步推进 Compose 的学习和实践。但是 Compose UI 工具包目前在部分场景下的组件支持有限,比如 WebView、CameraView 等,这些场景下仍需要配合 Android 原生的 View 方式来完成。
6.5 Sample
- 官方 Sample:
完全使用 Compose 设计的八大主流场景的 App:官方出品,专业、全面。
https://github.com/android/compose-samples
Movie 客户端
本人使用 Compose 的大部分 UI 组件、视图切换和数据刷新重构的电影搜索 App。
https://github.com/ellisonchan/ComposeMovie
- 俄罗斯方块
fun 神将自定义 Compose 组件和状态管理发挥到了极致,搭配定时器和各式动画实现,非常值得用来深入学习 Compose 技术。
https://github.com/vitaviva/compose-tetris
ComposeBird
本人在 fun 神的俄罗斯方块游戏的激励下使用 Compose 复刻了风靡一时的 Flappy Bird,感兴趣的也可以学习实现思路。
https://github.com/ellisonchan/ComposeBird
未来展望
本次介绍了 MAD 涵盖的诸多新技术,大家可以感受到 Google 在一刻不停地革新技术。从工具到语言、框架到发行方式都在进行全方位地改良,之前耕耘多年的技术说废就废,绝不手软。
究其原因,绕不开产品生命的两大角色:开发者和消费者。
提升开发者的开发效率
改善消费者的产品体验
然而新事物的出现必然伴随着旧事物的衰落,开发者该如何对待老技术、如何看待层出不穷、前途不明的新技术?光跨平台这一项,Google 和 Jetbrains 就推出了 Flutter、KMM、Compose Multiplatform 三个技术,任何人都卷不过来的。
我总结了几句四字短语,与你分享我的感受和态度:
不可无视,适当了解,跟上形势:保持关注,防止日后看不懂人家用了什么技术,甚至无法理解别人的代码
拥抱变化,勇于尝鲜,有备无患:找个感兴趣的切入点虚心学习、体会新技术的动机
不可依赖,了解原理,学习模仿:光使用还不够,需要深入了解其实现,确保坑来临的时候游刃有余
是否深入,见仁见智,自行评估:适当取舍、甚至观望,一些技术是昙花一现的
资料资源
官方资料
各类学习点的文档主页,主页和分支页面从背景、思想、API到使用方法等层面进行了充分说明。可以帮助你快速了解和掌握相关技术。
官方 Sample
Google优秀的开发者关系工程师的诚心之作,针对语言、工具和框架开发和持续维护着详尽的Sample。辅助大家学习这些技术,并进行适当地借鉴。
学习对象 地址
我的文章
Compose 系列:
「Jetpack Compose 助我快速打造电影 App」
「一气呵成:用Compose完美复刻Flappy Bird!」
Jetpack 系列:
「深度解读 Jetpack 框架的基石-AppCompat」
「为什么推荐使用 Jetpack CameraX?」
「Android 上数据库的新选择,Jetpack Room」
「Jetpack Hilt 有哪些改善又有哪些限制 」
「从Preference组件的更迭看Jetpack的前世今生」
「CameraX + 华为 ScanKit:二维码扫描的终极解决方案」
「Jetpack新成员SplashScreen:打造全新的App启动画面」
「Jetpack 叒一新成员 DragAndDrop 框架:大大简化拖放手势开发」
我的 Sample