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

1. 简介
Jetpack Compose是在2019Google i/O大会上发布的新的库。Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速度(这一段是谷歌自己说的)。 说实话,View/Layout的模式对安卓工程师来说太过于熟悉,对于学习曲线陡峭的Jetpack Compose能不能很好的普及还是有所担心。
因为Jetpack Compose的内容比较多,我会分成多个文章来进行介绍。 内容包括常用UI组件的使用,Flow和Compose的结合使用,以及如何构建MVVM应用。 还有,Compose的API还没有完全的确定下来,如果有API的修改,我也会对文章进行修订,所以敬请放心。
第1弹将会介绍如何创建Compose应用以及基本注解,Compose方法的使用。 好了,闲话不多说,开整!
2. 教程
2.1 创建新的项目或导入库
Jetpack Compose是从Android Studio 4.2开始支持的,所以需要通过4.2(现在是canary版本)创建新的项目或者添加导入库。这里按照创建新的项目来进行介绍。

根据上图所示,在创建新的项目时需要选择Empty Compose Activity。
此时模块中的build.gradle文件会新增下列的库的依赖。
dependencies {
...
implementation 'androidx.ui:ui-layout:"${compose_version}"'
implementation 'androidx.ui:ui-material:"${compose_version}"'
implementation 'androidx.ui:ui-tooling:"${compose_version}"'
...
}
还有在模块的build.gradle文件中新增下列的设置。
android {
...
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion "${compose_version}"
kotlinCompilerVersion "1.3.70-dev-withExperimentalGoogleExtensions-20200424"
}
}
2.2 UI相关
2.2.1 @Compose
所有关于构建View的方法都必须添加@Compose的注解才可以。并且@Compose跟协程的Suspend的使用方法比较类似,被@Compose的注解的方法只能在同样被@Comopse注解的方法中才能被调用。
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
2.2.2 @Preview
加上@Preview注解的方法可以在不运行App的情况下就可以确认布局的情况。
@Preview的注解中比较常用的参数如下:
name: String: 为该Preview命名,该名字会在布局预览中显示。showBackground: Boolean: 是否显示背景,true为显示。backgroundColor: Long: 设置背景的颜色。showDecoration: Boolean: 是否显示Statusbar和Toolbar,true为显示。group: String: 为该Preview设置group名字,可以在UI中以group为单位显示。fontScale: Float: 可以在预览中对字体放大,范围是从0.01。widthDp: Int: 在Compose中渲染的最大宽度,单位为dp。heightDp: Int: 在Compose中渲染的最大高度,单位为dp。
上面的参数都是可选参数,还有像背景设置等的参数并不是对实际的App进行设置,只是对Preview中的背景进行设置,为了更容易看清布局。
@Preview(showBackground = true, name = "Home UI", showDecoration = true)
@Composable
fun DefaultPreview() {
MyApplicationTheme {
Greeting("Android")
}
}
在IDE的右上角有Code,Split,Design三个选项。分别是只显示代码,同时显示代码和布局和只显示布局。
当更改跟UI相关的代码时,会显示如下图的一个横条通知,点击Build&Refresh即可更新显示所更改代码的UI。

2.2.3 setContent
setContent的作用是和zaiLayout/View中的setContentView是一样的。
setContent的方法也是有@Compose注解的方法。所以,在setContent中写入关于UI的@Compopse方法,即可在Activity中显示。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JetpackComposeDemoTheme {
Greeting("Android")
}
}
}
2.2.4 *Theme
在创建新的Compose项目时会自动创建一个项目名+Theme的@Compose方法。 我们可以通过更改颜色来完成对主题颜色的设置。 生成的Theme方法的代码如下。
private val DarkColorPalette = darkColorPalette(
primary = purple200,
primaryVariant = purple700,
secondary = teal200
)
private val LightColorPalette = lightColorPalette(
primary = purple500,
primaryVariant = purple700,
secondary = teal200
/* Other default colors to override
background = Color.White,
surface = Color.White,
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color.Black,
onSurface = Color.Black,
*/
)
@Composable
fun JetpackComposeDemoTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = typography,
shapes = shapes,
content = content
)
}
Theme方法中有正常主题和Dark主题的颜色设置,里面还有关于MeterialTheme的设置。
关于Theme方法的用法如下。
setContent {
JetpackComposeDemoTheme {
Greeting("Android")
}
}
在JetpackComposeDemoTheme里面的所有UI方法都会应用上述主题中指定的颜色。
2.2.4 Modifier
Modifier是各个Compose的UI组件一定会用到的一个类。它是被用于设置UI的摆放位置,padding等信息的类。关于Modifier相关的设置实在是太多,在这里只介绍会经常用到的。
padding设置各个UI的padding。padding的重载的方法一共有四个。
Modifier.padding(10.dp) // 给上下左右设置成同一个值
Modifier.padding(10.dp, 11.dp, 12.dp, 13.dp) // 分别为上下左右设值
Modifier.padding(10.dp, 11.dp) // 分别为上下和左右设值
Modifier.padding(InnerPadding(10.dp, 11.dp, 12.dp, 13.dp))// 分别为上下左右设值
plus可以把其他的Modifier加入到当前的Modifier中。
Modifier.plus(otherModifier) // 把otherModifier的信息加入到现有的modifier中
fillMaxHeight,fillMaxWidth,fillMaxSize类似于match_parent,填充整个父layout。
Modifier.fillMaxHeight() // 填充整个高度
width,heigh,size设置Content的宽度和高度。
Modifier.width(2.dp) // 设置宽度
Modifier.height(3.dp) // 设置高度
Modifier.size(4.dp, 5.dp) // 设置高度和宽度 复制代码
widthIn,heightIn,sizeIn设置Content的宽度和高度的最大值和最小值。
Modifier.widthIn(2.dp) // 设置最大宽度
Modifier.heightIn(3.dp) // 设置最大高度
Modifier.sizeIn(4.dp, 5.dp, 6.dp, 7.dp) // 设置最大最小的宽度和高度
gravity在Column中元素的位置。
Modifier.gravity(Alignment.CenterHorizontally) // 横向居中
Modifier.gravity(Alignment.Start) // 横向居左
Modifier.gravity(Alignment.End) // 横向居右
rtl,ltr开始布局UI的方向。
Modifier.rtl // 从右到左
Modifier.ltr // 从左到右 复制代码`</pre>
Modifier的方法都返回Modifier的实例的链式调用,所以只要连续调用想要使用的方法即可。
<pre>`@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!", modifier = Modifier.padding(20.dp).fillMaxSize())
}
2.2.5 Column,Row
正如其名字一样,Column和Row可以理解为在View/Layout体系中的纵向和横向的ViewGroup。
需要传入的参数一共有四个。
Modifier用上述的方法传入已经按需求设置好的Modifier即可。Arrangement.Horizontal,Arrangement.Vertical需要给Row传入Arrangement.Horizontal,为Column传入Arrangement.Vertical。 这些值决定如何布置内部UI组件。
可传入的值为Center,Start,End,SpaceEvenly,SpaceBetween,SpaceAround。 重点解释一下SpaceEvenly,SpaceBetween,SpaceAround。
SpaceEvenly:各个元素间的空隙为等比例。

SpaceBetween:第一元素前和最后一个元素之后没有空隙,所有空隙都按等比例放入各个元素之间。

SpaceAround:把整体中一半的空隙平分的放入第一元素前和最后一个元素之后,剩余的一半等比例的放入各个元素之间。

Alignment.Vertical,Alignment.Horizontal需要给Row传入Alignment.Vertical,为Column传入Alignment.Horizontal。 使用方法和Modifier的gravity中传入参数的用法是一样的,这里就略过了。@Composable ColumnScope.() -> Unit需要传入标有@Compose的UI方法。但是这里我们会有lamda函数的写法来实现。
整体代码如下。
Column {
Row(modifier = Modifier.ltr.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceAround, verticalGravity = Alignment.Top) {
// ..,...
}

3. 其他
客观地讲,Compose 确实是一套比较难学的东西,因为它毕竟太新也太大了,它是一个完整的、全新的框架,确实让很多人感觉「学不动」,这也是个事实。
那怎么办呢?学不动怎么办呢?
如果你是因为缺少学习资料,而我正好薅到这本谷歌内部大佬根据实战编写的《Jetpack Compose最全上手指南》,从入门到精通,教程通俗易懂,实例丰富,既有基础知识,也有进阶技能,能够帮助读者快速入门,是你学习Jetpack Compose的葵花宝典,快收藏起来!!!
第一章 初识 Jetpack Compose
1. 为什么我们需要一个新的UI 工具?
2. Jetpack Compose的着重点
- 加速开发
- 强大的UI工具
- 直观的Kotlin API

3. API 设计

4. Compose API 的原则
- 一切都是函数
- 顶层函数(Top-level function)
- 组合优于继承
- 信任单一来源

5. 深入了解Compose
- Core
- Foundation
- Material

6. 插槽API
第二章 Jetpack Compose构建Android UI
1. Android Jetpack Compose 最全上手指南
- Jetpack Compose 环境准备和Hello World
- 布局
- 使用Material design 设计
- Compose 布局实时预览
- ……

2. 深入详解 Jetpack Compose | 优化 UI 构建
- Compose 所解决的问题
- Composable 函数剖析
- 声明式 UI
- 组合 vs 继承
- 封装
- 重组
- ……

3. 深入详解 Jetpack Compose | 实现原理
- @Composable 注解意味着什么?
- 执行模式
- Positional Memoization (位置记忆化)
- 存储参数
- 重组
- ……

第三章 Jetpack Compose 项目实战演练(附Demo)
1. Jetpack Compose应用1
- 开始前的准备
- 创建DEMO
- 遇到的问题

2. Jetpack Compose应用2
3. Jetpack Compose应用做一个倒计时器
- 数据结构
- 倒计时功能
- 状态模式
- Compose 布局
- 绘制时钟

4. 用Jetpack Compose写一个玩安卓App
- 准备工作
- 引入依赖
- 新建 Activity
- 创建 Compose
- PlayTheme
- 画页面
- 底部导航栏
- 管理状态
- 添加页面

5. 用Compose Android 写一个天气应用
- 开篇
- 画页面
- 画背景
- 画内容
- ……

6. 用Compose快速打造一个“电影App”
- 成品
- 实现方案
- 实战
- 不足
- ……

需要的朋友只需要 点赞支持一下 后,然后【点击这里免费获取】
Android全新UI编程 - Jetpack Compose 超详细教程的更多相关文章
- c++ 网络编程课设入门超详细教程 ---目录
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9663167.html c++ 网络编程(一)TCP/UDP windows/linux 下入门 ...
- c++ 网络编程(九)LINUX/windows-IOCP模型 多线程超详细教程及多线程实现服务端
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html 先讲Linux下(windows下在后面可以直接跳到后面看): 一.线程 ...
- Github上传代码菜鸟超详细教程【转】
最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- Struts2+Spring4+Hibernate4整合超详细教程
Struts2.Spring4.Hibernate4整合 超详细教程 Struts2.Spring4.Hibernate4整合实例-下载 项目目的: 整合使用最新版本的三大框架(即Struts2.Sp ...
- 安装64位Oracle 10g超详细教程
安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...
- NumPy 超详细教程(3):ndarray 的内部机理及高级迭代
系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 ndarray 对象的内部机理 ...
- NumPy 超详细教程(2):数据类型
系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 NumPy 数据类型 ...
- NumPy 超详细教程(1):NumPy 数组
系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 Numpy 数组:n ...
随机推荐
- nginx访问fastdfs文件 报错400 Bad Request
1.修改vi /etc/fdfs/mod_fastdfs.conf 2.将url_have_group_name = false 改为 url_have_group_name = true 3.重启 ...
- Netty 框架学习 —— UDP 广播
UDP 广播 面向连接的传输(如 TCP)管理两个网络端点之间的连接的建立,在连接的生命周期的有序和可靠的消息传输,以及最后,连接的有序终止.相比之下,类似 UDP 的无连接协议中则没有持久化连接的概 ...
- 大话Java代理模式
一.什么是代理 首先理解一下什么是代理.简单来说,代理就你要做一件事情,我替你把事情做了.这是现实生活中我们遇到的代理的需求场景.但写代码的时候对代理场景的需求,跟现实场景有点区别,本质上还是帮你做事 ...
- mongodb数据的导出导入
1.[导出]mongoexport -h (主机名) -d (库) -c (集合名) -o (路径) -u (账号) -p (密码)示例:mongoexport -h localhost -d jav ...
- leetcode 字符串转换整数 (模拟)
思路分析 1.跟着题意模拟,分成几种情况来看待 2.一种全是空格 3.有可能有空格,然后有符号的 4.有可能有空格,无符号数字 5.有可能有空格,非数字开头 6.最后还需要考虑一个越界的问题,所以要除 ...
- git rebase(变基)操作
1.rebase(变基)操作 注意事项:rebase 改变分支的根源,绝对不要在与其他人共享的分支上进行操作rebase黄金法则:绝不要在公共的分支上使用它! 1.1git merge 与 git r ...
- .h .cpp区别
首先,我们可以将所有东西都放在一个.cpp文件内. 然后编译器就将这个.cpp编译成.obj,obj是什么东西? 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你 ...
- EXCEL:宏 考场考号打印
Sub addwork() Rem 当前宏是根据学生数量 .每考场人数计算工作表数Dim i As IntegerRem xx为每个考场的人数Rem yy为当前专业标记Rem mm为当前专业考生人数R ...
- 做词云时报错cannot import name ‘WordCloud‘ from partially initialized module ‘wordcloud‘的解决办法
问题: 在做词云时,运行时出现该问题,wordcloud安装成功,但运行出错,错误提示是:cannot import name 'WordCloud' from partially initializ ...
- RPC远程协议之原理分析
在近几年工作中发现,功能服务化或微服务化越来越流行,逐渐成为实现中大型分布式系统架构的主要方式,而在分布式系统中的不同节点应用间的通信中,RPC远程协议扮演关键作用.实际上,在日常工作中,我们也多多少 ...