Android Jetpack Compose 入门教程
一、什么是 Jetpack Compose?
Jetpack Compose 是 Android 官方推出的现代化 UI 工具包,它使用声明式的方式来构建用户界面。与传统的 XML 布局相比,Compose 具有以下优势:
- 声明式 UI:描述 UI 应该是什么样子,而不是如何构建
- 更少的代码:相比 XML 布局,代码量减少约 50%
- 实时预览:在 Android Studio 中可以实时预览 UI 效果
- Kotlin 原生:完全使用 Kotlin 编写,与 Kotlin 语言特性完美结合
1.1 安装或更新 Android Studio
- 一台可以联网的电脑
- 安装或更新到 最新版的 Android Studio
- 选择创建 Empty Activity

1.2 Composable 函数
第一步:Composable 函数
Jetpack Compose 是围绕着 Composable 函数建立的。这些函数让你通过描述它的形状和数据依赖性,以编程方式定义你的 UI,而不是专注于 UI 的构建过程。要创建一个 Composable 函数,只需在函数名称中添加 @Composable 注解。
setContent 块定义了一个我们可以调用 Composable 函数的 avtivity 的布局,Composable 函数只能从其他的 Composable 函数中调用
Composable 函数只能从其他 Composable 函数的范围内调用。要写一个 Composable 函数,我们需要添加一个 @Composable 的注解。
1 2 3 4 5 6 7 8
| class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text("Hello world!") } } }
|
1.3 预览函数
在 Android Studio 中预览你的函数
Android Studio 可以让你在 IDE 中预览你的 Composable 函数,而不需要将应用下载到 Android 设备或模拟器上。但是有个限制, 需要预览的 Composable 函数必须不能有任何参数。因为这个限制,你不能直接预览 MessageCard() 函数。但是,你可以尝试写第一个叫 PreviewMessageCard() 的函数,它调用带有参数的 MessageCard()。在 @Composable 之前添加 @Preview 注解。
界面
UI 元素是分层次的,元素包含在其他元素中。在 Compose 中,你可以通过从其他 Composable 函数中调用 Composable 函数来建立一个 UI 层次结构。
1 2 3 4 5 6 7 8 9 10
| @Composable fun MessageCard(name: String) { Text (text = "Hello $name!") }
@Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }
|
二、Compose 基础概念
2.1 @Composable 注解
@Composable 是 Compose 中最核心的注解,它标记一个函数为「可组合函数」。可组合函数用于构建 UI 组件。
如果没有这个注解,你的代码会从 “可组合的 UI 组件” 彻底变成普通的 Kotlin 函数,无法实现 UI 渲染,还会触发一系列编译和运行时问题
1 2 3 4 5
| @Composable fun Greeting(name: String) { Text(text = "Hello, $name!") }
|
解析:
@Composable 注解告诉编译器这是一个 UI 组件函数- 函数名使用帕斯卡命名法(首字母大写)
- 函数可以接收参数,用于动态显示内容
2.2 Modifier 修饰符
Modifier 是 Compose 中用于修改组件样式、布局和行为的核心工具。
为了修饰和配置一个 Composable, Compose 使用了 modifier,它们允许你改变 Composable 的尺寸、布局、外观或添加高级交互,比如可以让一个元素变得可以点击。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Composable fun MessageCard(msg: Message) { Row( modifier = Modifier.padding(all = 8.dp) ) { Image( painterResource(id = R.drawable.profile_picture), contentDescription = "profile picture", modifier = Modifier .size(50.dp) .clip(CircleShape) ) Spacer(Modifier.padding(horizontal = 8.dp)) Column { Text(text = msg.author) Spacer(Modifier.padding(vertical = 4.dp)) Text(text = msg.body) } } }
|
常用 Modifier 方法:
.padding() - 设置内边距.background() - 设置背景颜色.fillMaxWidth() - 填充父容器宽度.size() - 设置固定尺寸.border() - 设置边框.clickable() - 添加点击事件
2.3 Material design
Jetpack Compose 提供了 Material Design 的实现,我们将使用 Material Design 的风格来改善我们的 MessageCard。
Material Design 是围绕三个元素建立的。颜色(Color)、排版(Typography)、形状(Shape)。
一个 Empty Compose Activity 已经自动为你的项目生成了一个默认的主题,允许你自定义 MaterialTheme。如果你给你的项目命名与 ExamplesTheme 不同,你可以在 ui.theme 包中找到你的自定义主题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ExamplesTheme { MessageCard(Message("Jetpack Compose 博物馆", "我们开始更新啦")) } } }
@Preview @Composable fun PreviewMessageCard() { ExamplesTheme { MessageCard( msg = Message("Jetpack Compose 博物馆", "我们开始更新啦") ) } }
|
颜色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Row( modifier = Modifier.padding(all = 8.dp) ) { Image( painterResource(id = R.drawable.profile_picture), contentDescription = "profile picture", modifier = Modifier .size(50.dp) .clip(CircleShape) .border(1.5.dp, MaterialTheme.colors.secondary, shape = CircleShape) ) Spacer(Modifier.padding(horizontal = 8.dp)) Column { Text( text = msg.author, color = MaterialTheme.colors.secondaryVariant ) Spacer(Modifier.padding(vertical = 4.dp)) Text(text = msg.body) } }
|
排版
1 2 3 4 5 6 7 8 9 10 11 12
| Column { Text( text = msg.author, color = MaterialTheme.colors.secondaryVariant, style = MaterialTheme.typography.subtitle2 ) Spacer(Modifier.padding(vertical = 4.dp)) Text( text = msg.body, style = MaterialTheme.typography.body2 ) }
|
形状
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @Composable fun MessageCard(msg: Message) { Surface( shape = MaterialTheme.shapes.medium, elevation = 5.dp, modifier = Modifier.padding(all = 8.dp) ) { Row( modifier = Modifier.padding(all = 8.dp) ) { Image( painterResource(id = R.drawable.profile_picture), contentDescription = "profile picture", modifier = Modifier .size(50.dp) .clip(CircleShape) .border(1.5.dp, MaterialTheme.colors.secondary, shape = CircleShape) ) Spacer(Modifier.padding(horizontal = 8.dp)) Column { Text( text = msg.author, color = MaterialTheme.colors.secondaryVariant, style = MaterialTheme.typography.subtitle2 ) Spacer(Modifier.padding(vertical = 4.dp)) Text( text = msg.body, style = MaterialTheme.typography.body2 ) } } } }
|
启用深色主题
深色主题(或夜间模式)可以避免明亮的显示,由于支持 Material Design,Jetpack Compose 默认可以处理深色主题。只要是使用了 Material 的颜色后,文本和背景将自动适应黑暗的背景。
让我们添加一个新的预览注解并在手机上或者虚拟机上启用夜间模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Preview(name = "Light Mode") @Preview( uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true, name = "Dark Mode" ) @Composable fun PreviewMessageCard() { ExamplesTheme { MessageCard( msg = Message("Jetpack Compose 博物馆", "我们开始更新啦") ) } }
|
3.4 列表和动画
创建一个列表消息卡片
使用 Compose 的 LazyColumn 和 LazyRow。
在这个代码片段中,你可以看到 LazyColumn 有一个 items 子项。它接收一个 List 作为参数,它的 lambda 接收一个我们命名为 message 的参数(我们可以随便命名)。 而这个 lambda 将会调用每个 List 中里面提供的 item。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import androidx.compose.foundation.lazy.items
@Composable fun Conversation(messages: List<Message>) { LazyColumn { items(messages) { message -> MessageCard(msg = message) } } }
@Composable fun PreviewMessageCard() { ExamplesTheme { Conversation(messages = MsgData.messages) } }
|
3.5 可交互的动画效果
我们将会实现当点击一个卡片查看详细内容的时候,使内容的大小和背景颜色都有动画效果。为了存储这个本地 UI 状态,我们需要跟踪一条消息是否已经展开了。为了跟踪这种状态变化,我们必须使用 remember 和 mutableStateOf 函数。
Composable 函数可以通过使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。当值被更新时,使用该状态的 Composable 函数(及其子函数)将被自动重新绘制。我们把这称为重组(recomposition)。
通过使用 Compose 的状态 API,如 remember 和 mutableStateOf,任何对状态的改变都会自动更新 UI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Composable fun MessageCard(msg: Message) {
var isExpanded by remember { mutableStateOf(false) }
Surface( shape = MaterialTheme.shapes.medium, elevation = 5.dp, modifier = Modifier .padding(all = 8.dp) .clickable { isExpanded = !isExpanded } ) { Row( modifier = Modifier.padding(all = 8.dp) ) { Image( painterResource(id = R.drawable.profile_picture), contentDescription = "profile picture", modifier = Modifier .size(50.dp) .clip(CircleShape) .border(1.5.dp, MaterialTheme.colors.secondary, shape = CircleShape) ) Spacer(Modifier.padding(horizontal = 8.dp)) Column { Text( text = msg.author, color = MaterialTheme.colors.secondaryVariant, style = MaterialTheme.typography.subtitle2 ) Spacer(Modifier.padding(vertical = 4.dp)) Text( text = msg.body, style = MaterialTheme.typography.body2, maxLines = if (isExpanded) Int.MAX_VALUE else 1, modifier = Modifier.animateContentSize() ) } } } }
|
使用 isExpanded 来做点其他的事情吧!比如改变卡片的颜色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| val surfaceColor by animateColorAsState( targetValue = if (isExpanded) Color(0xFFCCCCCC) else MaterialTheme.colors.surface )
Surface( shape = MaterialTheme.shapes.medium, elevation = 5.dp, modifier = Modifier .padding(all = 8.dp) .clickable { isExpanded = !isExpanded }, color = surfaceColor ) { ... ... }
|
3.6 Alertdialog
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Composable fun AlertDialog( onDismissRequest: () -> Unit, confirmButton: () -> Unit, modifier: Modifier = Modifier, dismissButton: () -> Unit = null, title: () -> Unit = null, text: () -> Unit = null, shape: Shape = MaterialTheme.shapes.medium, backgroundColor: Color = MaterialTheme.colors.surface, contentColor: Color = contentColorFor(backgroundColor), properties: DialogProperties = DialogProperties() ): @Composable Unit
|
3.7 BaseAlertDialog
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| val openDialog = remember { mutableStateOf(true) } if (openDialog.value) { BasicAlertDialog( onDismissRequest = { openDialog.value = false }, modifier = Modifier .padding(0.dp) .size(width = 600.dp, height = 200.dp)
) { Surface( modifier = Modifier .fillMaxWidth(0.8f),
shape = RoundedCornerShape(16.dp), tonalElevation = 8.dp ) { Column( modifier = Modifier.padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "BasicAlertDialog", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 12.dp) ) Text( text = "我是完全自定义的内容,可以放文字、按钮、图片等任意组件", style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(bottom = 24.dp) ) Spacer(modifier = Modifier.padding(bottom = 2.dp)) Button( onClick = { openDialog.value = false }, modifier = Modifier .align(Alignment.End) .size(width = 80.dp, height = 50.dp) .padding(bottom = 0.dp) ) { Text(text = "关闭") } } } } }
|
三、基础布局组件
3.1 Column - 垂直布局
Column 函数可以让你垂直地排列元素(从上到下)。
用 Row 来水平排列项目,用 Box 来堆叠元素。
1 2 3 4 5 6 7
| @Composable inline fun Column( modifier: Modifier? = Modifier, verticalArrangement: Arrangement.Vertical? = Arrangement.Top, horizontalAlignment: Alignment.Horizontal? = Alignment.Start, content: (@Composable @ExtensionFunctionType ColumnScope.() -> Unit)? ): Unit
|
verticalArrangment 和 horizontalAlignment 参数分别可以帮助我们安排子项的垂直/水平位置,在默认的情况下,子项会以垂直方向上靠上(Arrangment.Top),水平方向上靠左(Alignment.Start)来排布
高度,那么就能使用 verticalArrangement 参数来定位子项在 Column 中的垂直位置。
宽度,那么就能使用 horizontalAlignment 参数来定位子项在 Column 中的水平位置。
大小,那么就可以同时使用以上的两个参数来定位子项的水平/垂直位置

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| Column { Text( text = "Hello, World!", style = MaterialTheme.typography.h6 ) Text("Jetpack Compose") }
Column( modifier = Modifier .border(1.dp, Color.Black) ) { Text( text = "Hello, World!", style = MaterialTheme.typography.h6 ) Text("Jetpack Compose") }
Column( modifier = Modifier .border(1.dp, Color.Black) .size(150.dp), verticalArrangement = Arrangement.Center ) { Text( text = "Hello, World!", style = MaterialTheme.typography.h6, modifier = Modifier.align(Alignment.CenterHorizontally) ) Text("Jetpack Compose") }
|
3.2 Row - 水平布局
Row 用于水平排列子组件(从左到右)。
事实上,Arrangment 就是来帮助我们快速安排好子项的位置,除了 Center(居中), Start(水平靠左), End(水平靠右)

1 2 3 4 5 6 7
| @Composable inline fun Row( modifier: Modifier? = Modifier, horizontalArrangement: Arrangement.Horizontal? = Arrangement.Start, verticalAlignment: Alignment.Vertical? = Alignment.Top, content: (@Composable @ExtensionFunctionType RowScope.() -> Unit)? ): Unit
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| Surface( shape = RoundedCornerShape(8.dp), modifier = Modifier .padding(horizontal = 12.dp) .fillMaxWidth(), elevation = 10.dp ) { Column( modifier = Modifier.padding(12.dp) ) { Text( text = "Jetpack Compose 是什么?", style = MaterialTheme.typography.h6 ) Spacer(Modifier.padding(vertical = 5.dp)) Text( text = "Jetpack Compose 是用于构建原生 Android 界面的新工具包。它可简化并加快 Android 上的界面开发,使用更少的代码、强大的工具和直观的 Kotlin API,快速让应用生动而精彩。" ) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { IconButton( onClick = { } ) { Icon(Icons.Filled.Favorite, null) } IconButton( onClick = { }, ) { Icon(painterResource(id = R.drawable.chat), null) } IconButton( onClick = { }, ) { Icon(Icons.Filled.Share, null) } } } }
|
3.3 Box - 层叠布局
Box 用于层叠排列子组件,后面的组件会覆盖在前面的组件之上。
1 2 3 4 5 6 7 8 9 10 11 12
| @Composable Box { Box( modifier = Modifier.size(150.dp).background(Color.Green) ) Box( modifier = Modifier.size(80.dp).background(Color.Red) ) Text( text = "世界" ) }
|
四、常用 UI 组件
4.1 Text 文本组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Composable fun TextExample() { Text( text = "Hello Android", color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center, modifier = Modifier .padding(16.dp) .background(Color.Blue) .fillMaxWidth() ) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Composable fun ButtonExample() { val buttonEnabled = remember { mutableStateOf(true) } Button( onClick = { buttonEnabled.value = false println("按钮被点击了!") }, modifier = Modifier .padding(16.dp) .fillMaxWidth(), enabled = buttonEnabled.value, colors = ButtonDefaults.buttonColors( backgroundColor = Color.Green, contentColor = Color.White ), shape = RoundedCornerShape(8.dp), elevation = ButtonDefaults.elevation( defaultElevation = 4.dp, pressedElevation = 8.dp ) ) { Text("点击我") } }
|
4.3 Image 图片组件
1 2 3 4 5 6 7 8 9 10 11 12
| @Composable fun ImageExample() { Image( painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = "应用图标", modifier = Modifier .size(100.dp) .clip(RoundedCornerShape(16.dp)) .border(2.dp, Color.Black), contentScale = ContentScale.Crop ) }
|
4.4 Surface 表面组件
Surface 是一个带有材质设计效果的容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Composable fun SurfaceExample() { Surface( modifier = Modifier .padding(16.dp) .fillMaxWidth() .height(100.dp), elevation = 8.dp, shape = RoundedCornerShape(16.dp), color = MaterialTheme.colors.primary ) { Column( modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.Center ) { Text("Surface 示例", style = MaterialTheme.typography.h6) Text("这是一个带有阴影的容器") } } }
|
五、列表和滚动
5.1 LazyColumn - 垂直懒加载列表
LazyColumn 用于显示大量数据,只会渲染可见区域的内容,性能高效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Composable fun LazyColumnExample() { val items = List(100) { "Item $it" } LazyColumn { items(items) { item -> Text( text = item, modifier = Modifier .padding(16.dp) .fillMaxWidth() .background(Color.LightGray) ) } } }
|
5.2 Spacer - 间距组件
Spacer 用于在布局中创建空白间距。
1 2 3 4 5 6 7 8 9
| @Composable fun SpacerExample() { Column { Text("上面的文本") Spacer(modifier = Modifier.height(16.dp)) Text("下面的文本") Spacer(modifier = Modifier.width(32.dp)) } }
|
六、状态管理
6.1 remember 和 mutableStateOf
在 Compose 中,使用 remember 和 mutableStateOf 来管理组件的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Composable fun CounterExample() { val count = remember { mutableStateOf(0) } Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Text("计数器: ${count.value}", fontSize = 24.sp) Button( onClick = { count.value++ } ) { Text("增加") } Button( onClick = { count.value = 0 } ) { Text("重置") } } }
|
七、主题和样式
7.1 使用 MaterialTheme
MaterialTheme 提供了统一的主题配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Composable fun MyApp() { MaterialTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { Column( modifier = Modifier.padding(16.dp) ) { Text( "标题", style = MaterialTheme.typography.h4, color = MaterialTheme.colors.primary ) Text( "正文", style = MaterialTheme.typography.body1 ) } } } }
|
八、完整示例
8.1 简单的待办事项应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| @Composable fun TodoApp() { val todos = remember { mutableStateListOf("学习 Compose", "写代码", "测试应用") } val newTodo = remember { mutableStateOf("") } Column( modifier = Modifier.padding(16.dp) ) { Text( "待办事项", style = MaterialTheme.typography.h4, modifier = Modifier.padding(bottom = 16.dp) ) Row { TextField( value = newTodo.value, onValueChange = { newTodo.value = it }, placeholder = { Text("输入新事项") }, modifier = Modifier.weight(1f) ) Button( onClick = { if (newTodo.value.isNotBlank()) { todos.add(newTodo.value) newTodo.value = "" } }, modifier = Modifier.padding(start = 8.dp) ) { Text("添加") } } Spacer(modifier = Modifier.height(16.dp)) LazyColumn { items(todos) { todo -> Card( modifier = Modifier .fillMaxWidth() .padding(vertical = 4.dp), elevation = 2.dp ) { Row( modifier = Modifier.padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween ) { Text(todo) IconButton( onClick = { todos.remove(todo) } ) { Icon(Icons.Default.Delete, "删除") } } } } } } }
|
九、排列与对齐
9.1 按钮
9.2 文本输入框
9.3 图片
9.4 复选框
1 2 3 4 5 6 7 8 9 10 11
| Checkbox( checked = isChecked.value, onCheckedChange = { isChecked.value = it }, colors = CheckboxDefaults.colors( checkedColor = androidx.compose.ui.graphics.Color.Blue, uncheckedColor = androidx.compose.ui.graphics.Color.Gray, checkmarkColor = androidx.compose.ui.graphics.Color.White ), enabled = true )
|
9.5 单选按钮
快捷键Shift+F6快速格式化
1 2 3 4 5 6 7 8 9 10 11
| RadioButton( selected = isSelected.value, onClick = { isSelected.value = true }, colors = RadioButtonDefaults.colors( selectedColor = androidx.compose.ui.graphics.Color.Blue, unselectedColor = androidx.compose.ui.graphics.Color.Gray ), enabled = true )
|
9.6 开关
1 2 3 4 5 6 7 8 9 10 11 12 13
| Switch( checked = isChecked.value, onCheckedChange = { isChecked.value = it }, colors = SwitchDefaults.colors( checkedThumbColor = androidx.compose.ui.graphics.Color.Blue, uncheckedThumbColor = androidx.compose.ui.graphics.Color.Gray, checkedTrackColor = androidx.compose.ui.graphics.Color.LightGray, uncheckedTrackColor = androidx.compose.ui.graphics.Color.DarkGray ), enabled = true )
|
9.7 下拉菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| DropdownMenu( expanded = isExpanded.value, onDismissRequest = { isExpanded.value = false }, modifier = Modifier.padding(8.dp) ) { DropdownMenuItem( onClick = { isExpanded.value = false } ) { Text("选项1") } } stringArrayResource(id = R.array.countryList)
|
9.8 Toast消息提示
1 2
| Toast.makeText(context, "这是一条 Toast 消息", Toast.LENGTH_SHORT).show()
|
9.9 Snackbar消息提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| SnackbarHost( hostState = snackbarHostState, modifier = Modifier.padding(16.dp) ) Scaffold( topBar = { TopAppBar( title = { Text("待办事项") } ) } )
LaunchedEffect(key1 = Unit) { snackbarHostState.showSnackbar("这是一条 Snackbar 消息") } SnackbarDuration.Indefinite @OptIn(ExperimentalMaterial3Api::class)
|
9.10 对话框消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| AlertDialog( onDismissRequest = { }, title = { Text("确认删除") }, text = { Text("确定要删除选中项吗?") }, confirmButton = { Button( onClick = { } ) { Text("确认") } }, dismissButton = { Button( onClick = { } ) { Text("取消") } } )
按钮Button
Button( onClick = { } ) { Text("点击我") }
IconButton( onClick = { } ) { Icon(Icons.Default.Delete, contentDescription = "删除") }
|
9.11 顶部应用栏
1 2 3 4
| TopAppBar( title = { Text("待办事项") } )
|
9.12 选项菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| DropdownMenu( expanded = isExpanded.value, onDismissRequest = { isExpanded.value = false }, modifier = Modifier.padding(8.dp) ) { DropdownMenuItem( onClick = { isExpanded.value = false } ) { Text("选项1") } }
|
9.13 导航四部分
1 2 3 4 5 6 7 8 9
| NavigationBar { NavigationBarItem( selected = currentRoute == "home", onClick = { navigateTo("home") }, icon = { Icon(Icons.Filled.Home, contentDescription = "首页") } ) }
|
9.14 列表
1 2 3 4 5 6 7 8
| LazyColumn { items(items) { item -> ListItem( text = { Text(item) } ) } }
|
9.15 懒加载Column四部分
1 2 3 4 5 6 7 8
| LazyColumn { items(items) { item -> ListItem( text = { Text(item) } ) } }
|
9.16 懒加载Row
1 2 3 4 5 6 7 8
| LazyRow { items(items) { item -> ListItem( text = { Text(item) } ) } }
|
9.17 懒加载Grid
1 2 3 4 5 6 7 8 9 10 11
| LazyVerticalGrid( columns = GridCells.Fixed(2), modifier = Modifier.padding(8.dp) ) { items(items) { item -> ListItem( text = { Text(item) } ) } }
|
9.18 待办事项列表五部分
1 2 3 4 5 6 7 8
| LazyColumn { items(items) { item -> ListItem( text = { Text(item) } ) } }
|
9.19 约束布局
1 2 3 4
| BoxWithConstraints { }
|
9.20 TextView文本视图
1 2 3 4 5
| Text( text = "这是一条文本消息", modifier = Modifier.padding(16.dp) )
|
9.21 列表项imageView图片视图
1 2 3 4 5 6 7 8 9 10
| ListItem( text = { Text("列表项") }, icon = { Image( painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = "图标" ) } )
|
9.22 滚动视图
九、开发技巧
9.1 代码格式化
在 Android Studio 中,可以使用 Ctrl + Alt + L(Windows/Linux)或 Cmd + Option + L(Mac)来格式化代码。
9.2 实时预览
在函数上方添加 @Preview 注解,可以在 Android Studio 中实时预览 UI 效果:
1 2 3 4 5
| @Preview(showBackground = true) @Composable fun PreviewExample() { Text("这是预览文本") }
|
9.3 调试技巧
- 使用
println() 在 Logcat 中输出调试信息 - 使用
Modifier.background(Color.Red) 临时添加背景色来查看组件边界 - 使用 Android Studio 的 Layout Inspector 查看组件层次结构
十、学习路径建议
对于初学者,建议按照以下顺序学习:
- 基础概念:理解 @Composable、Modifier、状态管理
- 布局组件:掌握 Column、Row、Box 的使用
- 常用组件:学习 Text、Button、Image 等基础组件
- 列表和滚动:掌握 LazyColumn 的使用
- 主题和样式:学习 MaterialTheme 的应用
- 高级特性:学习动画、导航、架构等
总结
Jetpack Compose 是 Android 开发的未来趋势,它让 UI 开发变得更加简单、直观。通过本教程,你应该已经掌握了 Compose 的基础知识。继续练习和探索,你会发现 Compose 的强大之处!
记住:实践是最好的学习方式!