Jetpack Compose 实践入门:从环境搭建到待办列表实现

Jetpack Compose 是 Google 推出的现代化 UI 开发工具包,基于声明式编程范式,彻底改变了 Android 传统的 XML 布局开发模式。它通过 Kotlin 语言的特性,让 UI 开发更简洁、高效,同时具备更强的可组合性和可维护性。本文将从实践角度出发,带大家从环境搭建开始,逐步掌握 Compose 的核心用法,并最终实现一个简易待办列表应用。

一、环境搭建

在使用 Jetpack Compose 前,需先完成开发环境的配置,确保工具和依赖满足要求。

1.1****基础环境要求

  • Android Studio 版本:需升级至 Arctic Fox(2020.3.1)及以上,推荐使用最新稳定版(如 Hedgehog),旧版本不支持 Compose 的完整功能。
  • Kotlin 版本:需与 Android Studio 兼容,建议使用 1.6.0 及以上版本(可在项目根目录的 build.gradle 中配置)。
  • Min SDK 版本:最低支持 API 21(Android 5.0),若需使用部分高级功能,建议设置为 API 24 及以上。

1.2****新建 Compose 项目

  1. 打开 Android Studio,选择「Start a new Android Studio project」。
  1. 在模板列表中,选择「Empty Activity」,点击「Next」。
  1. 配置项目信息:填写 Application name、Package name、Save location,Language 选择「Kotlin」。
  1. 关键配置:勾选「Use Jetpack Compose」,此时 Android Studio 会自动配置 Compose 相关依赖和插件,Minimum SDK 建议选择 24,点击「Finish」。

1.3****手动配置现有项目(可选)

若需在现有项目中集成 Compose,需手动修改以下配置:

1.3.1****根目录 build.gradle

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| groovy buildscript { ext { compose_version = '1.4.3' // 推荐使用稳定版 } dependencies { // 确保 Kotlin 插件版本与项目一致 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20" } } |

1.3.2****模块目录 build.gradle Module level

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| groovy plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { compileSdk 34 defaultConfig { applicationId "com.example.composepractice" minSdk 24 targetSdk 34 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } // 启用 Compose buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion compose_version } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } } dependencies { // Compose 基础依赖 implementation "androidx.compose.ui:ui:compose_version" implementation "androidx.compose.material:material:compose_version" implementation "androidx.compose.ui:ui-tooling-preview:compose_version" implementation 'androidx.activity:activity-compose:1.8.2' // 测试依赖 testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "androidx.compose.ui:ui-test-junit4:compose_version" debugImplementation "androidx.compose.ui:ui-tooling:compose_version" debugImplementation "androidx.compose.ui:ui-test-manifest:compose_version" } |

**二、**Jetpack Compose 核心概念

在开始编写代码前,需先理解 Compose 的几个核心概念,这是掌握其开发模式的关键。

2.1****可组合函数( Composable Function

Compose 的 UI 构建基础是「可组合函数」,即被 @Composable 注解标记的 Kotlin 函数。这类函数不返回任何值,而是直接描述 UI 应该呈现的样子。

|----------------------------------------------------------------------------------------------|
| kotlin // 简单的可组合函数示例 @Composable fun Greeting(name: String) { Text(text = "Hello, $name!") } |

注意:可组合函数只能在其他可组合函数内部调用,或在 Compose 支持的上下文(如 Activity 的 setContent 中)调用。

2.2****声明式 UI

传统 Android 开发采用命令式 UI,需通过 findViewById 获取控件实例,再手动修改其属性(如 textView.setText("xxx"))。而 Compose 采用声明式 UI,开发者只需描述「状态对应的 UI 样子」,当状态发生变化时,Compose 会自动重新执行可组合函数,更新 UI。

2.3****状态( State )与重组( Recomposition

「状态」是驱动 UI 变化的数据(如输入框内容、开关状态、列表数据等)。Compose 中,只有被「可观察状态」修饰的数据发生变化时,依赖该状态的可组合函数才会被重新执行,这个过程称为「重组」。重组是局部的,只会更新受影响的 UI 部分,保证性能高效。

常用的可观察状态 API:remember(保存状态,避免重组时丢失)、mutableStateOf(创建可观察的状态容器)。

三、基础控件实践

Compose 提供了一系列基础控件,如 Text、Button、TextField、Image 等,下面通过实践讲解其核心用法。

3.1****文本控件( Text

Text 用于显示文本,支持设置字体大小、颜色、粗细、换行方式等属性,通过 style 或 modifier 配置。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomText() { Column( modifier = Modifier.padding(16.dp) // 内边距 ) { // 基础文本 Text(text = "基础文本") // 带样式的文本 Text( text = "大号加粗红色文本", fontSize = 20.sp, // sp 适配字体大小,需导入 androidx.compose.ui.unit.sp color = Color.Red, fontWeight = FontWeight.Bold, modifier = Modifier.padding(top = 8.dp) ) // 多行文本 Text( text = "这是一段很长的多行文本,当文本内容超过一行时,会自动换行显示。如果需要限制最大行数,可以设置maxLines属性。", maxLines = 2, overflow = TextOverflow.Ellipsis, // 超出部分显示省略号 modifier = Modifier.padding(top = 8.dp) ) } } |

3.2****按钮控件( Button

Button 用于触发点击事件,支持设置文本、图标、样式等,点击事件通过 onClick 参数配置。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomButton() { Column(modifier = Modifier.padding(16.dp)) { // 基础按钮 Button(onClick = { /* 点击事件逻辑 */ }) { Text(text = "基础按钮") } // 带图标的按钮 Button( onClick = { /* 点击事件逻辑 */ }, modifier = Modifier.padding(top = 8.dp) ) { Icon( imageVector = Icons.Default.Add, // 系统默认图标 contentDescription = "添加", // 无障碍描述 modifier = Modifier.size(ButtonDefaults.IconSize) ) Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing)) // 图标与文本间距 Text(text = "带图标按钮") } // 禁用状态的按钮 Button( onClick = { /* 禁用时点击事件不生效 */ }, enabled = false, modifier = Modifier.padding(top = 8.dp) ) { Text(text = "禁用按钮") } } } |

3.3****输入控件( TextField

TextField 用于接收用户输入,需与状态绑定,实时更新输入内容。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomTextField() { // 定义可观察状态,保存输入内容 var inputText by remember { mutableStateOf("") } Column(modifier = Modifier.padding(16.dp)) { TextField( value = inputText, // 绑定状态 onValueChange = { inputText = it }, // 输入变化时更新状态 label = { Text(text = "请输入内容") }, // 提示文本 placeholder = { Text(text = "例如:学习 Compose") }, // 占位文本 modifier = Modifier.fillMaxWidth(), // 占满宽度 singleLine = true // 单行输入 ) // 显示输入的内容 Text( text = "你输入的内容:$inputText", modifier = Modifier.padding(top = 16.dp) ) } } |

3.4****图片控件( Image

Image 用于显示图片,支持网络图片、本地资源图片等,需配合 painter 指定图片源。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomImage() { Column(modifier = Modifier.padding(16.dp)) { // 显示本地资源图片(需在 drawable 目录放置图片) Image( painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = "本地图片", modifier = Modifier .size(100.dp) .clip(CircleShape), // 圆形裁剪 contentScale = ContentScale.Crop // 缩放模式 ) // 显示网络图片(需添加 coil 依赖,处理网络图片加载) // 1. 添加依赖:implementation "io.coil-kt:coil-compose:2.4.0" AsyncImage( model = "https://picsum.photos/200/200", // 网络图片地址 contentDescription = "网络图片", modifier = Modifier .size(100.dp) .padding(top = 16.dp), contentScale = ContentScale.Crop ) } } |

四、布局系统实践

Compose 采用「基于 Modifier 的布局系统」,通过 Column(垂直布局)、Row(水平布局)、Box(层叠布局)等基础布局容器,结合 Modifier 的属性(如 padding、margin、size、weight 等),实现复杂的 UI 布局。

4.1****垂直布局( Column

Column 用于垂直排列子控件,默认自上而下排列,可通过 horizontalAlignment 控制子控件水平对齐方式,verticalArrangement 控制子控件垂直间距。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomColumn() { Column( modifier = Modifier .padding(16.dp) .fillMaxWidth() .background(Color.LightGray) .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, // 水平居中 verticalArrangement = Arrangement.SpaceBetween // 子控件均匀分布 ) { Text(text = "顶部文本") Text(text = "中间文本") Text(text = "底部文本") } } |

4.2****水平布局( Row

Row 用于水平排列子控件,默认自左向右排列,可通过 verticalAlignment 控制子控件垂直对齐方式,horizontalArrangement 控制子控件水平间距。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomRow() { Row( modifier = Modifier .padding(16.dp) .fillMaxWidth() .background(Color.LightGray) .padding(16.dp), verticalAlignment = Alignment.CenterVertically, // 垂直居中 horizontalArrangement = Arrangement.SpaceAround // 子控件均匀分布,两侧留空 ) { Icon(imageVector = Icons.Default.Home, contentDescription = "首页") Text(text = "导航栏") Icon(imageVector = Icons.Default.Person, contentDescription = "我的") } } |

4.3****层叠布局( Box

Box 用于层叠排列子控件,后添加的子控件会覆盖在前一个子控件上方,可通过 contentAlignment 控制子控件的对齐方式。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun CustomBox() { Box( modifier = Modifier .padding(16.dp) .size(200.dp) .background(Color.Blue) ) { // 底层文本 Text( text = "底层文本", color = Color.White, fontSize = 24.sp, modifier = Modifier.align(Alignment.Center) // 居中对齐 ) // 顶层图标(覆盖在文本上方) Icon( imageVector = Icons.Default.Star, contentDescription = "星星", color = Color.Yellow, modifier = Modifier .size(40.dp) .align(Alignment.TopEnd) // 右上角对齐 ) } } |

五、实战:简易待办列表应用

结合前面所学的知识,我们实现一个简易的待办列表应用,具备「添加待办」「删除待办」「标记待办完成」功能。

5.1****定义数据模型

首先定义待办项的数据类,包含 id、内容、是否完成三个属性。

|---------------------------------------------------------------------------------------------------------|
| kotlin // Todo.kt data class Todo( val id: Int, val content: String, val isCompleted: Boolean = false ) |

5.2****实现待办列表页面

页面包含三部分:输入待办的 TextField 和添加按钮、待办列表(使用 LazyColumn 实现滚动列表)、待办项(包含复选框、文本、删除按钮)。

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin @Composable fun TodoListScreen() { // 待办列表状态(可观察) var todoList by remember { mutableStateOf(listOf<Todo>()) } // 输入内容状态 var inputContent by remember { mutableStateOf("") } // 用于生成唯一 id var nextId by remember { mutableStateOf(1) } Column(modifier = Modifier.padding(16.dp)) { // 输入区域 Row(modifier = Modifier.fillMaxWidth()) { TextField( value = inputContent, onValueChange = { inputContent = it }, label = { Text(text = "添加待办") }, modifier = Modifier.weight(1f), // 占满剩余宽度 singleLine = true ) Button( onClick = { // 添加待办(非空判断) if (inputContent.isNotBlank()) { todoList = todoList + Todo(id = nextId++, content = inputContent) inputContent = "" // 清空输入框 } }, modifier = Modifier.padding(start = 8.dp) ) { Text(text = "添加") } } // 待办列表(LazyColumn 实现懒加载,优化性能) LazyColumn( modifier = Modifier .fillMaxWidth() .weight(1f) .padding(top = 16.dp) ) { items(todoList) { todo -> TodoItem( todo = todo, onToggleCompleted = { // 标记待办完成/未完成 todoList = todoList.map { if (it.id == todo.id) it.copy(isCompleted = !it.isCompleted) else it } }, onDelete = { // 删除待办 todoList = todoList.filter { it.id != todo.id } } ) } } } } // 单个待办项 @Composable fun TodoItem( todo: Todo, onToggleCompleted: () -> Unit, onDelete: () -> Unit ) { Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp) .background(Color.LightGray, shape = RoundedCornerShape(8.dp)) .padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { // 复选框(标记完成状态) Checkbox( checked = todo.isCompleted, onCheckedChange = { onToggleCompleted() } ) // 待办内容(完成状态下添加删除线) Text( text = todo.content, modifier = Modifier.weight(1f), style = if (todo.isCompleted) { TextStyle(textDecoration = TextDecoration.LineThrough, color = Color.Gray) } else { TextStyle() } ) // 删除按钮 IconButton(onClick = { onDelete() }) { Icon( imageVector = Icons.Default.Delete, contentDescription = "删除", color = Color.Red ) } } } |

5.3****在 Activity 中加载页面

修改 MainActivity,在 setContent 中调用 TodoListScreen 可组合函数。

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ComposePracticeTheme { // 项目默认的主题 Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background ) { TodoListScreen() // 加载待办列表页面 } } } } } |

5.4****运行效果

  1. 输入待办内容,点击「添加」按钮,待办项会显示在列表中。

  2. 点击复选框,可标记待办为完成状态(文本添加删除线)。

  3. 点击删除按钮,可移除对应的待办项。

六、进阶方向

本文讲解的是 Jetpack Compose 的基础实践,若需深入学习,可关注以下进阶方向:

  • 状态管理进阶:使用 ViewModel + StateFlow 管理全局状态,替代本地 remember 状态。
  • 导航:集成 Jetpack Navigation Compose,实现多页面跳转。
  • 主题与样式:自定义 Compose 主题,统一 UI 风格。
  • 动画:使用 Compose 内置动画 API(如 animateDpAsState、AnimatedVisibility)实现过渡动画。
  • 性能优化:学习重组优化、懒加载列表优化等技巧。

总结

Jetpack Compose 通过声明式编程和可组合函数,简化了 Android UI 开发流程。本文从环境搭建开始,逐步讲解了核心概念、基础控件、布局系统,并通过待办列表实战整合了所学知识。希望通过本文的实践的,能帮助大家快速上手 Compose,感受现代化 UI 开发的便捷。后续可结合官方文档和实际项目,进一步深化对 Compose 的理解和使用。

相关推荐
赏金术士6 小时前
Kotlin ViewModel
android·kotlin
vistaup8 小时前
kotlin 二维码实现高斯模糊
android·kotlin
愈努力俞幸运8 小时前
function calling与mcp
android·数据库·redis
阿巴斯甜9 小时前
LeakCanary
android
阿巴斯甜9 小时前
compose
android
阿巴斯甜10 小时前
Glide
android
-SOLO-10 小时前
使用Perfetto debug trace查看超时slice
android
阿巴斯甜10 小时前
Retrofit
android
阿巴斯甜10 小时前
OkHttp
android
阿巴斯甜10 小时前
Flow
android