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 的理解和使用。

相关推荐
冬奇Lab4 小时前
稳定性性能系列之二——ANR机制深度解析:从触发到上报
android·性能优化·debug
江上清风山间明月4 小时前
Android BIND_NOTIFICATION_LISTENER_SERVICE 权限详解
android·notification·service·bind·listener
Lei活在当下4 小时前
【日常知识积累】Kotlin let 函数、inline 函数以及 DSL
android·kotlin·编程语言
世界美景5 小时前
一种基于 ART 内存特征的 LSPosed/Xposed/分身环境 完美检测方案
android·安全·安卓·xposed
2501_946230986 小时前
Cordova&OpenHarmony外观主题设置
android·javascript
小韩博6 小时前
小迪之盲注第44课
android·网络安全·adb
夏沫琅琊7 小时前
Android TestDPC 工程详解
android
键来大师7 小时前
Android16 AP热点修改默认密码为12345678
android·framework·rk3576·android16
李坤林7 小时前
Android KGI (Generic Kernel Image)
android