目录
- 一、引言:Android Jetpack
- 1.Jetpack是什么?
- 2. 常用的Jetpack库
- 二、Compose的基本概念
- 1.什么是Jetpack Compose
- 2.Compose的编程思想
- 三、 Compose简单的案例: 一个倒计时效果
- 1.构建一个Compose项目
- 2.声明一个倒计时的UI
- 3.利用线程使其动起来
- 4.实现效果
- 四、总结
一、引言:Android Jetpack
1.Jetpack是什么?
Jetpack 是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。
2. 常用的Jetpack库
- activity: 访问基于 activity 构建的可组合 API。
链接: activity - appcompat:允许在平台的旧版 API 上访问新 API(很多使用 Material Design)。
链接: appcompat - appsearch:为用户构建自定义应用内搜索功能。
链接: appsearcht - camera:构建移动相机应用。
链接: camera - compose:使用描述界面形状和数据依赖项的可组合函数,以编程方式定义界面。
链接: compose
二、Compose的基本概念
1.什么是Jetpack Compose
Jetpack Compose是用于构建原生Android UI的现代工具包。 Jetpack Compose使用更少的代码,强大的工具和直观的Kotlin API,简化并加速了Android上的UI开发。
2.Compose的编程思想
Jetpack Compose 是一个适用于 Android 的新式声明性界面工具包。Compose 提供声明性 API,让您可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。
1. 声明性编程范式
1.长期以来,Android 视图层次结构一直可以表示为界面 widget 树。由于应用的状态会因用户交互等因素而发生变化,因此界面层次结构需要进行更新以显示当前数据。最常见的界面更新方式是使用 findViewById() 等函数遍历树,并通过调用 button.setText(String)、container.addChild(View) 或 img.setImageBitmap(Bitmap) 等方法更改节点。这些方法会改变 widget 的内部状态。
2.在过去的几年中,整个行业已开始转向声明性界面模型,该模型大大简化了与构建和更新界面关联的工程任务。该技术的工作原理是在概念上从头开始重新生成整个屏幕,然后仅执行必要的更改。此方法可避免手动更新有状态视图层次结构的复杂性。Compose 是一个声明性界面框架。
3.重新生成整个屏幕所面临的一个难题是,在时间、计算能力和电池用量方面可能成本高昂。为了减少在这方面耗费的资源,Compose 会智能地选择在任何给定时间需要重新绘制界面的哪些部分。这会对您设计界面组件的方式有一定影响,如重组中所述。
2. 简单的可组合函数
使用 Compose,您可以通过定义一组接受数据而发出界面元素的可组合函数来构建界面。
关于此函数,有几点值得注意:
- 此函数带有 @Composable 注释。所有可组合函数都必须带有此注释;此注释可告知 Compose 编译器:此函数旨在将数据转换为界面。
- 此函数带有 @Composable 注释。所有可组合函数都必须带有此注释;此注释可告知 Compose 编译器:此函数旨在将数据转换为界面。
- 此函数接受数据。可组合函数可以接受一些参数,这些参数可让应用逻辑描述界面。在本例中,我们的 widget 接受一个 String,因此它可以按名称问候用户。
- 此函数可以在界面中显示文本。为此,它会调用 Text() 可组合函数,该函数实际上会创建文本界面元素。可组合函数通过调用其他可组合函数来发出界面层次结构。
- 此函数不会返回任何内容。发出界面的 Compose 函数不需要返回任何内容,因为它们描述所需的屏幕状态,而不是构造界面 widget。
- 此函数快速、幂等且没有附带效应。
使用同一参数多次调用此函数时,它的行为方式相同,并且它不使用其他值,如全局变量或对 random() 的调用。
此函数描述界面而没有任何副作用,如修改属性或全局变量。
一般来说,出于重组部分所述的原因,所有可组合函数都应使用这些属性来编写。
示例:
一个简单的示例是 Greeting widget,它接受 String 并发出一个显示问候消息的 Text widget。
3. 声明性范式转变
1.在许多面向对象的命令式界面工具包中,您可以通过实例化 widget 树来初始化界面。您通常通过膨胀 XML 布局文件来实现此目的。每个 widget 都维护自己的内部状态,并且提供 getter 和 setter 方法,允许应用逻辑与 widget 进行交互。
2.在 Compose 的声明性方法中,widget 相对无状态,并且不提供 setter 或 getter 函数。实际上,widget 不会以对象形式提供。您可以通过调用带有不同参数的同一可组合函数来更新界面。这使得向架构模式(如 ViewModel)提供状态变得很容易,如应用架构指南中所述。然后,可组合项负责在每次可观察数据更新时将当前应用状态转换为界面。
界面描述:自上而下
应用逻辑为顶级可组合函数提供数据。该函数通过调用其他可组合函数来使用这些数据描述界面,将适当的数据传递给这些可组合函数,并沿层次结构向下传递数据。
事件响应:自下而上
例如当用户与界面交互时,界面会发起 onClick 等事件。这些事件应通知应用逻辑,应用逻辑随后可以改变应用的状态。当状态发生变化时,系统会使用新数据再次调用可组合函数。这会导致重新绘制界面元素,此过程称为“重组”。
4. 动态内容
由于可组合函数是用 Kotlin 而不是 XML 编写的,因此它们可以像其他任何 Kotlin 代码一样动态。
例如,假设您想要构建一个界面,用来问候一些用户:
@Composable
fun Greeting(names: List<String>) {
for (name in names) {
Text("Hello $name")
}
}
此函数接受名称的列表,并为每个用户生成一句问候语。可组合函数可能非常复杂。您可以使用 if 语句来确定是否要显示特定的界面元素。您可以使用循环。您可以调用辅助函数。您拥有底层语言的全部灵活性。这种强大的功能和灵活性是 Jetpack Compose 的主要优势之一。
5. 重组
在命令式界面模型中,如需更改某个 widget,您可以在该 widget 上调用 setter 以更改其内部状态。在 Compose 中,您可以使用新数据再次调用可组合函数。这样做会导致函数进行重组 – 系统会根据需要使用新数据重新绘制函数发出的 widget。Compose 框架可以智能地仅重组已更改的组件。
例如,假设有以下可组合函数,它用于显示一个按钮:
@Composable
fun ClickCounter(clicks: Int, onClick: () -> Unit) {
Button(onClick = onClick) {
Text("I've been clicked $clicks times")
}
}
每次点击该按钮时,调用方都会更新 clicks 的值。Compose 会再次调用 lambda 与 Text 函数以显示新值;此过程称为“重组”。不依赖于该值的其他函数不会进行重组。
三、 Compose简单的案例: 一个倒计时效果
1.构建一个Compose项目
- 打开 Andorid Studio
- 选择 Empty Compose Activity,点击next 3. 依次设置Name、Package name、save location对应信息, 由于Jetpack Compose 仅适用于使用 Kotlin 编写的类。在 Minimum API level dropdown 菜单中,选择 API 级别 21 或更高级别。
2.声明一个倒计时的UI
@Composable
fun run(count: Int) {
val arc = 1.7f
val inter = 0.3f
val num = 360/2
Canvas(modifier = Modifier
.size(200.dp)
) {
for(i in 0 until num) {
drawArc(Color.LightGray, -90-i*(arc+inter), arc,true)
}
}
Canvas(modifier = Modifier
.size(200.dp)
) {
for(i in 0 until count) {
drawArc(Brush.horizontalGradient(listOf(Color.Blue, Color.Yellow)), -90-i*(arc+inter), arc, true)
}
}
Canvas(modifier = Modifier.size(200.dp)) {
drawCircle(Color.White, radius = 200f)
}
Canvas(modifier = Modifier
.size(200.dp)
) {
drawArc(Color.Red, -90-count*2f-2f, 1.7f, true)
}
}
@Preview
@Composable
fun ClockPreview() {
run(8)
}
3.利用线程使其动起来
@Composable
fun CountDown() {
var count by remember{mutableStateOf(360/2)}
run(count = count)
Column {
Text(
text = ""+count,
)
}
thread {
Thread.sleep(100)
count--;
if (count <= 0) count = 360/2
}
}
4.实现效果
四、总结
以上介绍了前置知识Jetpack以及Compose的基本概念,并且实现一个案例来简单使用Compose。Compose不仅能够帮助轻松构建美观的原生应用,是一个高效率的安卓开发框架,而且Compose的声明式写法有利于架构思想的统一,并且声明式UI, 写起来更快, 不容易出错。
王振雷 链接:https://blog.csdn.net/Wzl11222/article/details/128149800?spm=1001.2014.3001.5502