本文是根据官方文档学习 作笔记记载
目录
- Composable functions (可组合函数)
- Layouts(文本,cloumn,图片,布置布局)
- Material Design (Color(色彩),Typography(排版),Shape(形状),启用深色主题)
- Lists and animations(列表和动画)
- 体会的一些运用技巧
Jetpack Compose 是 Google 推出的 用来构建 Android 用户界面的工具包,采用的是声明式的办法。(如果你触摸过 Flutter ,会有似曾相识的感觉。)关于本文的学习,如果你有 Kotlin 的开发根底, 一点Android 运用开发的常识,会轻松一点。
Composable functions
Compose 可组合函数是 Jetpack Compose 的根本构建块,用于定义UI 组件。
下面是一个简略示例 Greeting
widget ,接纳 String
参数 并经过 Text
widget 显现出来。
// ...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Greeting("AndroidDeveloper")
}
}
}
@Composable
fun Greeting(name: String) {
Text("Hello $name!")
}
关于此函数,有几点需求注意。
- @Composable 注解。这个注解告诉编译器,这个函数的意图是将数据转换为用户界面。
- 带有此注解的函数也被称为可组合函数,简称可组合函数。这些函数是 Compose 中用户界面的构件。增加此注解非常简略快捷,可协助您将用户界面组织成一个可重复运用的元素库
- 此函数接纳数据, 可组合函数可接纳参数,用于界面描绘。
- 此函数不回来任何内容 (但它会回来
Unit
),声明式命名组件,用于描绘屏幕状况而非构建界面widget。
在 Android Studio 预览你的函数
@Preview
注解 可协助你实时预览可组合函数,无需构建运用程序并安装在Android 设备或者浏览器。 该注释有必要用在不接受参数的可组合函数,因而无法直接预览 Greeting
的功用,需求创立一个 DefaultPreview
,传入参数去调用 Greeting
。
@Composable
fun Greeting(name: String) {
Text("Hello $name!")
}
@Preview(showBackground = true,widthDp = 360, heightDp = 360)
@Composable
fun DefaultPreview() {
Greeting(" Developer!")
}
-
@Preview
注解中各项装备可设置,供你预览作用。
Layouts
在制作页面时,UI元素是分层的, 元素包裹在其他元素中,(各种Layout,View 的嵌套),而在Compose 中,咱们能够经过其他组合函数调用可组合函数来构建UI层次结构。
到这儿,咱们现已知道 Compose 可组合函数 和 预览的用法了,接下来 是学会怎么运用布局去完善作用。
这儿我和官方文档相同 ,运用音讯列表 这个样例来学习。
增加多个文本
class SecondActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MessageCard(Message("Android", "Jetpack Compose"))
}
}
}
data class Message(val author: String, val body: String)
@Composable
fun MessageCard(msg: Message) {
Text(text = msg.author)
Text(text = msg.body)
}
从上图作用,咱们创立的两个 Text
元素,是会重叠在一起,原因是咱们未供给有关怎么摆放文本元素的信息。
运用 Column
Column
函数 能够垂直摆放 其布局内元素。 你也能够运用 Row
,Box
去实现想要的作用。
@Composable
fun MessageCard(msg: Message) {
Column() {
Text(text = msg.author)
Text(text = msg.body)
}
}
增加Image
@Composable
fun MessageCard(msg: Message) {
Row() {
Image(painter = painterResource(id = R.drawable.cat), contentDescription = "Contact profile picture")
Column() {
Text(text = msg.author)
Text(text = msg.body)
}
}
}
预览作用
现在看到的作用, 图片太大了, 间距也没有。这时候就需求就需求 Modifier
,点进Row 的源码能够看到默许参数是有 Modifier
,它的用途类似 将Android Layout 中的装备属性,做了一个调集,详细的各位能够看源码 或者文档, 我这儿就不细说了。
@Composable
fun MessageCard(msg: Message) {
Row() {
Image(
painter = painterResource(id = R.drawable.cat),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Column() {
Text(text = msg.author)
Spacer(modifier = Modifier.height(4.dp))
Text(text = msg.body)
}
}
}
这个作用比之前的好点了, Modifier
可玩性很高,更多功用各位能够自己去发掘。
Material Design
Compose 当然也是支持 Material Design 原则的, 它许多页面元素都原生支持 Material Design ,这儿我运用了 项目中创立的Material
主题 和 Surface
来修正了 MessageCard 的外观 。
Material Design 是环绕Color
、Typography
、Shape
这三大要素构建的。下面的代码将环绕这三大元素修正。
- 预览作用 & 主题文件位置
Color
运用 MaterialTheme.colors ,可用封装在主题的色彩来设置作用。
@Composable
fun MessageCard(msg: Message) {
Row() {
Image(
painter = painterResource(id = R.drawable.cat),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
**.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)**
)
Spacer(modifier = Modifier.width(8.dp))
Column() {
Text(text = msg.author, **color = MaterialTheme.colors.secondaryVariant**)
Spacer(modifier = Modifier.height(4.dp))
Text(text = msg.body)
}
}
}
- 预览作用
Typography
MaterialTheme.typography.*
这儿用在 text的 style 中
Shape
这块是我作为UI仔最喜欢的地方了,(整点花里胡哨的) 兄弟们,你看看这作用,就一句代码 !!就一句!! 不必写shape.xml , 不必盲猜了, 还能预览 !! 赶忙上号更新呀!
这儿设置了shape
的大小(有三种尺寸选择,咱们大部分的需求都能满足), 暗影加了1dp ,对了 ,各位发现没 ,直接是1.dp
@Composable
fun MessageCard(msg: Message) {
Row() {
Image(
painter = painterResource(id = R.drawable.cat),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Column() {
Text(
text = msg.author,
color = MaterialTheme.colors.secondary,
style = MaterialTheme.typography.subtitle2
)
Spacer(modifier = Modifier.height(4.dp))
**Surface(shape = MaterialTheme.shapes.medium, elevation = 1.dp)** {
Text(text = msg.body,modifier = Modifier.padding(all = 4.dp) , style = MaterialTheme.typography.body2)
}
}
}
深色主题
由于Jetpack Compose 默许支持 Material Design ,所以系统会自动适应深色布景
增加新的预览注解并启用夜间模式。
@Preview(name = "Light Mode")
@Preview(
uiMode = Configuration.UI_MODE_NIGHT_YES,
showBackground = true,
name = "Dark Mode"
)
@Preview(showBackground = true)
@Composable
fun PreviewMessageCard() {
MySootheTheme {
Surface {
MessageCard(
msg = Message("Lexi", "Hey, Look at this cute cat, it's so so lovely!")
)
}
}
}
这儿浅色和深色主题的色彩选项是在 IDE 生成 的 Theme.kt
中定义的。
Lists and animations
来到咱们常用的列表和动画了, 跟着官方文档学完后,我觉得这代码写起来真的变轻松了 。
创立音讯列表
这儿的子项items 接纳 传递 过来的参数list,lambda 省略了 遍历list这块代码 ,这儿的message 是自定义命名的,LazyColumn 顾名思义只加载屏幕上显现的内容,关于长列表布局会更高效。
保存状况 & 增加动画
到这儿,音讯列表的雏形就有了 ,在这块内容要做的是把一些过长的内容收起来,加上动画作用,把盯梢音讯是否打开储存为本地界面状况。 需求用到 **remember**
和 mutableStateOf
函数 。
**remember
** 可将本地状况存储在内存中,并把盯梢的值的改变传递给 mutableStateOf
。这个值的更新,系统会自动重新制作运用此状况的可组合项(及其子项),这叫重组,能够看下链接的官方解释。
经过运用 Compose 的状况 API(如remember
和mutableStateOf
),系统会在状况发生任何改变时自动更新界面。
@Composable
fun MessageCard(msg: Message) {
Row(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(id = R.drawable.cat),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
**var isExtended by remember { mutableStateOf(false) }**
Column(**Modifier.clickable { isExtended = !isExtended }**) {
Text(
text = msg.author,
color = MaterialTheme.colors.secondary,
style = MaterialTheme.typography.subtitle2
)
Spacer(modifier = Modifier.height(4.dp))
Surface(shape = MaterialTheme.shapes.medium, elevation = 1.dp) {
Text(
text = msg.body,
modifier = Modifier.padding(all = 4.dp),
style = MaterialTheme.typography.body2,
**maxLines = if (isExtended) Int.MAX_VALUE else 1**
)
}
}
}
}
- 预览作用
根据 isExpanded 盯梢的状况,修正打开和 收起来音讯的布景色彩 (运用 MaterialTheme.colors 的两种色彩)。 animateContentSize
音讯容器的动画作用。
@Composable
fun MessageCard(msg: Message) {
Row(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(id = R.drawable.cat),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
var isExpanded by remember { mutableStateOf(false) }
v**al surfaceColor by animateColorAsState(
if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
)**
Column(Modifier.clickable { isExpanded = !isExpanded }) {
Text(
text = msg.author,
color = MaterialTheme.colors.secondary,
style = MaterialTheme.typography.subtitle2
)
Spacer(modifier = Modifier.height(4.dp))
Surface(shape = MaterialTheme.shapes.medium, **color = surfaceColor**, elevation = 1.dp) {
Text(
text = msg.body,
modifier = Modifier.padding(all = 4.dp),
style = MaterialTheme.typography.body2,
maxLines = if (isExpanded) Int.MAX_VALUE else 1
)
}
}
}
}
-
最终加上 布景色的动态作用
以下是您目前为止所学的内容,一切内容只需不到 100 行代码!:
- 定义可组合函数
- 在可组合项中增加不同的元素
- 运用布局可组合项构建界面组件
- 运用修饰符扩展可组合项 Modifiers
- 创立高效列表
- 盯梢状况以及修正状况
- 在可组合项上增加用户互动
- 在打开音讯时显现动画作用
改善的技巧,发现了比我讲得好的博主,我这儿就不写了,共享给我们。