Compose 1
可组合函数
-
Compose是围绕可组合函数(Composable)构建的,只需要在可组合函数中描述界面和提供数据依赖,而不必关注界面的构建过程(初始化、添加到父布局等);
-
添加@Composable注解即可声明一个可组合函数;
-
可组合函数只能从其他可组合函数调用
-
借助@Preview注解,可以在AS中预览可组合函数,且因为该注解必须用于不接受参数的可组合函数,因此需要创建一个无参可组合函数.
@Composable fun MessageCard(name: String) { Text(text = "Hello $name!") } @Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }
布局
垂直排列
@Composable
fun MessageCard(msg: Message) {
Column {
Text(text = msg.author)
Text(text = msg.body)
}
}
@Preview
@Composable
fun MessageCardPreview() {
MessageCard(msg = Message("author_preview", "body_preview"))
}
水平排列
@Composable
fun MessageCard(msg: Message) {
Row {
Text(text = msg.author)
Text(text = msg.body)
}
}
@Preview
@Composable
fun MessageCardPreview() {
MessageCard(msg = Message("author_preview", "body_preview"))
}
堆叠排列
@Composable
fun MessageCard(msg: Message) {
Box {
Text(text = msg.author)
Text(text = msg.body)
}
}
@Preview
@Composable
fun MessageCardPreview() {
MessageCard(msg = Message("author_preview", "body_preview"))
}
配置布局
@Composable
fun MessageCard(msg: Message) {
Row {
Image(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = "image"
)
Column {
Text(text = msg.author)
Text(text = msg.body)
}
}
}
@Preview
@Composable
fun MessageCardPreview() {
MessageCard(msg = Message("author_preview", "body_preview"))
}
问题:
元素间距不合理
图片过大
@Composable
fun MessageCard(msg: Message) {
Row {
Image(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = "image",
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)
}
}
}
@Preview
@Composable
fun MessageCardPreview() {
MessageCard(msg = Message("author_preview", "body_preview"))
}
列表和动画
- 列表
@Composable
fun MessageList(messageList: List<Message>) {
LazyColumn {
items(messageList) { message ->
MessageCard(message)
}
}
}
@Preview
@Composable
fun MessageListPreview() {
LearnComposeTheme {
Surface {
val messageList: MutableList<Message> = mutableListOf()
messageList.add(Message("author1", "body1"))
messageList.add(Message("author2", "body2"))
messageList.add(Message("author3", "body3"))
messageList.add(Message("author4", "body4"))
MessageList(messageList = messageList)
}
}
}
-
动画
compose中使用rember存储本地状态,这个值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)
var isExpand by remember { mutableStateOf(false) }- remember确保mutableStateOf(false)创建的MutableState对象在充重组过程中保持其状态
- by将isExpand的访问和修改委托给MutableStateOf对象
- 通过by关键字,isExpand的getter和setter实际是通过MutableState对象实现的.当访问isExpand时,实际上是在调用MutableState对象的value属性的的getter方法,修改时用的就是setter方法,此时会触发Compose系统进行重组,从而更新UI.
@Composable inline fun <T> remember(crossinline calculation: @DisallowComposableCalls () -> T): T = currentComposer.cache(false, calculation)我们来看remember的实现:
- @Composable表示是可组合函数,只能在另一个可组合函数中调用
- inline表示这是个内联函数,编译时会把函数的代码体直接替换到调用点,从而消除函数调用的开销
- 表示泛型,rember函数可以记住任何类型的值
- crossinline用来修饰lambda,表示lambda不能有非局部返回,确保在被内联时不会意外的从外部函数返回.
- @DisallowComposableCalls表示这个lambda不能调用其他可组合函数,确保calculation中的代码不会破坏Compose的重组机制