Jetpack Compose Android 声明式 UI

FreeGuideOnline 最新 2026-07-10

kotlin android { buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.4" // 根据最新版本调整 } }

dependencies { implementation(platform("androidx.compose:compose-bom:2024.01.00")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.material3:material3") implementation("androidx.compose.ui:ui-tooling-preview") debugImplementation("androidx.compose.ui:ui-tooling") }


3. 同步项目,环境即准备完毕。

## 第一个可组合函数

任何一个被 `@Composable` 注解标记的函数都可以生成界面片段。让我们从经典的“Hello World”开始。

```kotlin
@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

在 Activity 中使用:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Greeting("Compose")
        }
    }
}

setContent 块内就是一个 Compose 作用域,你可以直接调用任何可组合函数。

基础组件

Compose 提供了一系列内置的可组合项,帮助你快速搭建界面。

Text

显示文本,支持设置颜色、字号、字重等。

Text(
    text = "欢迎学习 Compose",
    color = Color.Blue,
    fontSize = 20.sp,
    fontWeight = FontWeight.Bold
)

Button

按钮组件,用 onClick 处理点击事件。

Button(onClick = { /* 处理点击 */ }) {
    Text("点击我")
}

Image

显示本地或网络图片资源。

Image(
    painter = painterResource(id = R.drawable.ic_launcher),
    contentDescription = "图标"
)

TextField

文本输入框,需要维护一个状态变量来存储输入值。

var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("输入内容") }
)

其他常用组件

  • Surface:提供背景和边框的容器
  • Checkbox:复选框
  • RadioButton:单选框
  • Slider:滑动条

布局方式

Compose 采用“容器 + 内容”的模式进行布局,所有布局组件自身也是可组合函数。

Column(垂直排列)

Column {
    Text("第一行")
    Text("第二行")
}

Row(水平排列)

Row {
    Text("左")
    Text("右")
}

Box(层叠布局)

允许子元素重叠放置,可通过 alignment 控制定位。

Box {
    Image(...)
    Text("叠加文字", modifier = Modifier.align(Alignment.Center))
}

使用 Modifier 调整布局

Modifier 是 Compose 的万能修饰符,可控制尺寸、间距、对齐、背景等。

Column(
    modifier = Modifier
        .fillMaxSize()
        .padding(16.dp),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text("居中的文本")
}

常用 Modifier 扩展:

  • fillMaxWidth() / fillMaxSize()
  • size(width, height)
  • padding(all) / padding(horizontal, vertical)
  • background(color, shape)
  • border(width, color, shape)

状态管理与重组

在 Compose 中,当状态发生变化时,所有读取该状态的可组合函数会自动重新执行(重组),生成新的 UI。

使用 remember 与 mutableStateOf

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    Column {
        Text("Count: $count")
        Button(onClick = { count++ }) {
            Text("增加")
        }
    }
}
  • mutableStateOf 创建一个可观察的状态对象,值变化时触发重组
  • remember 确保在重组期间状态不会被重置

状态提升

将状态移动到更高的可组合函数中,实现状态共享和复用。

@Composable
fun Counter(count: Int, onIncrement: () -> Unit) {
    Column {
        Text("Count: $count")
        Button(onClick = onIncrement) {
            Text("增加")
        }
    }
}

父级持有状态并向下传递,这种方式被称为单向数据流

Material Design 3 主题

Compose 原生集成了 Material 3,可通过 MaterialTheme 访问颜色、字体、形状系统。

自定义主题

Theme.kt 中定义配色和排版:

private val LightColorScheme = lightColorScheme(
    primary = Color(0xFF6200EE),
    secondary = Color(0xFF03DAC6)
)

@Composable
fun MyAppTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = LightColorScheme,
        typography = Typography, // 自定义排版
        content = content
    )
}

使用时包裹需要应用主题的内容:

MyAppTheme {
    // 自动使用主题色
    Text("主题文本", color = MaterialTheme.colorScheme.primary)
}

列表与延迟加载

对于大量数据,使用 LazyColumnLazyRow 提升性能,它们只组合当前可见的项。

@Composable
fun NameList(names: List<String>) {
    LazyColumn {
        items(names) { name ->
            Text(text = name, modifier = Modifier.padding(8.dp))
        }
    }
}

导航

Compose 通过 Navigation Compose 库实现页面跳转。

添加依赖:

implementation("androidx.navigation:navigation-compose:2.7.5")

基本使用:

val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
    composable("home") { HomeScreen(navController) }
    composable("detail/{itemId}") { backStackEntry ->
        DetailScreen(itemId = backStackEntry.arguments?.getString("itemId"))
    }
}

导航触发:

Button(onClick = { navController.navigate("detail/123") }) {
    Text("去详情")
}

实战项目:备忘录应用

结合以上知识,我们快速搭建一个简单的备忘录界面。

1. 数据模型

data class Note(val id: Int, val content: String)

2. 界面组合

@Composable
fun NotesApp() {
    var notes by remember { mutableStateOf(listOf<Note>()) }
    var newNote by remember { mutableStateOf("") }

    Column(modifier = Modifier.padding(16.dp)) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            TextField(
                value = newNote,
                onValueChange = { newNote = it },
                modifier = Modifier.weight(1f),
                label = { Text("新备忘录") }
            )
            Spacer(modifier = Modifier.width(8.dp))
            Button(onClick = {
                if (newNote.isNotBlank()) {
                    notes = notes + Note(id = notes.size, content = newNote)
                    newNote = ""
                }
            }) {
                Text("添加")
            }
        }
        LazyColumn {
            items(notes) { note ->
                Card(modifier = Modifier.padding(vertical = 4.dp)) {
                    Text(note.content, modifier = Modifier.padding(12.dp))
                }
            }
        }
    }
}