本文是根据官方文档学习 作笔记记载

目录

  • 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!")
}

Jetpack Compose  中的基础知识

  • @Preview 注解中各项装备可设置,供你预览作用。

Jetpack Compose  中的基础知识

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)
}

Jetpack Compose  中的基础知识
从上图作用,咱们创立的两个 Text 元素,是会重叠在一起,原因是咱们未供给有关怎么摆放文本元素的信息。

运用 Column

Column 函数 能够垂直摆放 其布局内元素。 你也能够运用 RowBox 去实现想要的作用。

 @Composable
fun MessageCard(msg: Message) {
    Column() {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}

Jetpack Compose  中的基础知识

Jetpack Compose  中的基础知识

增加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)
        }
    }
}

预览作用

Jetpack Compose  中的基础知识
现在看到的作用, 图片太大了, 间距也没有。这时候就需求就需求 Modifier ,点进Row 的源码能够看到默许参数是有 Modifier ,它的用途类似 将Android Layout 中的装备属性,做了一个调集,详细的各位能够看源码 或者文档, 我这儿就不细说了。

Jetpack Compose  中的基础知识

@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)
        }
    }
}

Jetpack Compose  中的基础知识
这个作用比之前的好点了, Modifier 可玩性很高,更多功用各位能够自己去发掘。

Material Design

Compose 当然也是支持 Material Design 原则的, 它许多页面元素都原生支持 Material Design ,这儿我运用了 项目中创立的Material 主题 和 Surface 来修正了 MessageCard 的外观 。

Material Design 是环绕ColorTypographyShape这三大要素构建的。下面的代码将环绕这三大元素修正。

  • 预览作用 & 主题文件位置

Jetpack Compose  中的基础知识

Jetpack Compose  中的基础知识

Jetpack Compose  中的基础知识

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)
        }
    }
}
  • 预览作用

Jetpack Compose  中的基础知识

Typography

MaterialTheme.typography.* 这儿用在 text的 style 中

Jetpack Compose  中的基础知识

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  中的基础知识

深色主题

由于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!")
            )
        }
    }
}

Jetpack Compose  中的基础知识

这儿浅色和深色主题的色彩选项是在 IDE 生成 的 Theme.kt 中定义的。

Lists and animations

来到咱们常用的列表和动画了, 跟着官方文档学完后,我觉得这代码写起来真的变轻松了 。

创立音讯列表

这儿的子项items 接纳 传递 过来的参数list,lambda 省略了 遍历list这块代码 ,这儿的message 是自定义命名的,LazyColumn 顾名思义只加载屏幕上显现的内容,关于长列表布局会更高效。

Jetpack Compose  中的基础知识

保存状况 & 增加动画

到这儿,音讯列表的雏形就有了 ,在这块内容要做的是把一些过长的内容收起来,加上动画作用,把盯梢音讯是否打开储存为本地界面状况。 需求用到 **remember**mutableStateOf 函数 。

**remember** 可将本地状况存储在内存中,并把盯梢的值的改变传递给 mutableStateOf。这个值的更新,系统会自动重新制作运用此状况的可组合项(及其子项),这叫重组,能够看下链接的官方解释。

经过运用 Compose 的状况 API(如remembermutableStateOf),系统会在状况发生任何改变时自动更新界面。

@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**
                )
            }
        }
    }
}
  • 预览作用
Jetpack Compose  中的基础知识

根据 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
                )
            }
        }
    }
}
  • 最终加上 布景色的动态作用

Jetpack Compose  中的基础知识

以下是您目前为止所学的内容,一切内容只需不到 100 行代码!:

  • 定义可组合函数
  • 在可组合项中增加不同的元素
  • 运用布局可组合项构建界面组件
  • 运用修饰符扩展可组合项 Modifiers
  • 创立高效列表
  • 盯梢状况以及修正状况
  • 在可组合项上增加用户互动
  • 在打开音讯时显现动画作用

改善的技巧,发现了比我讲得好的博主,我这儿就不写了,共享给我们。

改善Jetpack Compose 的 12 个运用技巧