Android Jetpack Compose 基础控件介绍

Jetpack Compose 是 Google 推出的现代声明式 UI 工具包,用于构建 Android 原生界面,基于 Kotlin 语言设计,彻底改变了传统的 XML 布局方式,实现了「代码即 UI」的开发模式。本文将从核心概念、基础语法、组件使用、状态管理、布局系统等维度,结合完整的 Kotlin 代码示例,详细讲解 Compose 的使用方式。

一、核心概念

1.1 声明式编程

Compose 采用声明式 UI 范式:开发者只需描述 UI 的「最终状态」,Compose 自动处理 UI 的构建、更新和渲染,而非传统命令式编程中手动操作 View 的创建和修改。

kotlin 复制代码
// 声明式:描述"有一个文本,显示Hello Compose"
Text(text = "Hello Compose")

// 传统命令式(对比)
val textView = TextView(context)
textView.text = "Hello XML"
layout.addView(textView)

1.2 可组合函数(Composable)

Compose 的核心是可组合函数 ,通过 @Composable 注解标记,用于构建 UI 组件。

  • 只能在其他可组合函数中调用
  • 无返回值(专注描述 UI,而非返回 View)
  • 支持参数传递,实现组件复用

1.3 重组(Recomposition)

当可组合函数的输入参数(状态)发生变化时,Compose 会重新执行该函数,更新 UI 中变化的部分(仅更新差异),这一过程称为「重组」,是 Compose 实现 UI 响应式更新的核心。

二、环境配置

2.1 基础依赖(build.gradle.kts)

确保项目使用 Android Gradle Plugin 7.0+,并添加以下依赖:

kotlin 复制代码
plugins {
    id("com.android.application") version "8.2.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}

// 模块级 build.gradle.kts
android {
    compileSdk = 34
    buildFeatures {
        compose = true // 启用 Compose
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.3" // 与 Kotlin 版本匹配
    }
}

dependencies {
    // Compose 核心库
    implementation("androidx.compose.ui:ui:1.5.4")
    // Material Design 3(推荐)
    implementation("androidx.compose.material3:material3:1.1.2")
    // 预览功能
    implementation("androidx.compose.ui:ui-tooling-preview:1.5.4")
    // 活动集成
    implementation("androidx.activity:activity-compose:1.8.2")
    // 测试
    androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.5.4")
    debugImplementation("androidx.compose.ui:ui-tooling:1.5.4")
}

2.2 入口 Activity

Compose 不再需要 XML 布局,Activity 只需设置 Compose 内容:

kotlin 复制代码
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import androidx.activity.compose.setContent

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 设置 Compose 内容
        setContent {
            // 应用主题
            MyComposeAppTheme {
                // 填充整个屏幕
                Surface(modifier = Modifier.fillMaxSize()) {
                    // 自定义可组合函数
                    Greeting(name = "Compose")
                }
            }
        }
    }
}

// 应用主题(自动生成,可自定义)
@Composable
fun MyComposeAppTheme(
    darkTheme: Boolean = false,
    content: @Composable () -> Unit
) {
    val colorScheme = if (darkTheme) {
        MaterialTheme.colorScheme
    } else {
        MaterialTheme.colorScheme
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = MaterialTheme.typography,
        content = content
    )
}

三、基础可组合组件

3.1 文本(Text)

最基础的文本展示组件,支持样式、颜色、大小等配置:

kotlin 复制代码
@Composable
fun Greeting(name: String) {
    Text(
        text = "Hello, $name!",
        // 文本样式
        style = MaterialTheme.typography.headlineMedium,
        // 文本颜色
        color = MaterialTheme.colorScheme.primary,
        // 内边距
        modifier = Modifier.padding(16.dp)
    )
}

// 预览函数(无需运行应用即可查看 UI)
@Preview(showBackground = true, name = "Greeting Preview")
@Composable
fun GreetingPreview() {
    MyComposeAppTheme {
        Greeting("Android")
    }
}

3.2 按钮(Button)

可点击的按钮组件,支持点击事件、禁用状态等:

kotlin 复制代码
@Composable
fun ActionButton(onClick: () -> Unit) {
    Button(
        onClick = onClick,
        // 禁用状态
        enabled = true,
        // 形状
        shape = RoundedCornerShape(8.dp),
        // 内边距
        modifier = Modifier.padding(8.dp)
    ) {
        // 按钮内的内容(文本+图标)
        Row(verticalAlignment = Alignment.CenterVertically) {
            Icon(
                imageVector = Icons.Default.Send,
                contentDescription = "Send icon",
                modifier = Modifier.size(24.dp)
            )
            Spacer(modifier = Modifier.width(8.dp)) // 间距
            Text(text = "Submit")
        }
    }
}

// 预览
@Preview
@Composable
fun ActionButtonPreview() {
    MyComposeAppTheme {
        ActionButton(onClick = { /* 点击逻辑 */ })
    }
}

3.3 输入框(TextField)

文本输入组件,支持双向绑定、提示文本、验证等:

kotlin 复制代码
@Composable
fun NameInputField() {
    // 状态:用于双向绑定输入内容(remember 确保重组时状态不丢失)
    var name by remember { mutableStateOf("") }

    OutlinedTextField(
        value = name,
        onValueChange = { name = it }, // 双向绑定
        label = { Text("Enter your name") }, // 标签
        placeholder = { Text("e.g. John Doe") }, // 占位符
        leadingIcon = { Icon(Icons.Default.Person, contentDescription = "Person icon") },
        // 错误提示
        isError = name.length < 3,
        supportingText = {
            if (name.length < 3) {
                Text("Name must be at least 3 characters")
            }
        },
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    )
}

@Preview
@Composable
fun NameInputFieldPreview() {
    MyComposeAppTheme {
        NameInputField()
    }
}

3.4 图片(Image)

加载本地/网络图片(网络图片需配合 Coil 库):

kotlin 复制代码
// 本地图片
@Composable
fun LocalImage() {
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_foreground),
        contentDescription = "App icon", // 无障碍描述
        modifier = Modifier
            .size(64.dp)
            .clip(CircleShape) // 圆形裁剪
    )
}

// 网络图片(需添加 Coil 依赖:implementation("io.coil-kt:coil-compose:2.4.0"))
@Composable
fun NetworkImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "Network image",
        modifier = Modifier.size(128.dp),
        // 加载中占位符
        placeholder = painterResource(id = R.drawable.placeholder),
        // 错误占位符
        error = painterResource(id = R.drawable.error)
    )
}

四、布局系统

Compose 提供灵活的布局组件,核心布局包括:

4.1 线性布局(Row/Column)

  • Row:水平排列子组件
  • Column:垂直排列子组件
kotlin 复制代码
@Composable
fun LinearLayoutExample() {
    Column(
        // 垂直排列的对齐方式
        verticalArrangement = Arrangement.SpaceBetween,
        // 水平对齐方式
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        Text(text = "Top Text", style = MaterialTheme.typography.titleLarge)
        
        Row(
            horizontalArrangement = Arrangement.Center,
            modifier = Modifier.fillMaxWidth()
        ) {
            Button(onClick = {}) { Text("Button 1") }
            Spacer(modifier = Modifier.width(8.dp))
            Button(onClick = {}) { Text("Button 2") }
        }
        
        Text(text = "Bottom Text", style = MaterialTheme.typography.titleLarge)
    }
}

@Preview
@Composable
fun LinearLayoutPreview() {
    MyComposeAppTheme {
        LinearLayoutExample()
    }
}

4.2 盒子布局(Box)

层叠布局,子组件可重叠,支持对齐方式:

kotlin 复制代码
@Composable
fun BoxLayoutExample() {
    Box(
        modifier = Modifier
            .size(200.dp)
            .background(MaterialTheme.colorScheme.secondaryContainer),
        contentAlignment = Alignment.Center
    ) {
        // 底层组件
        Image(
            painter = painterResource(id = R.drawable.background),
            contentDescription = null,
            modifier = Modifier.fillMaxSize()
        )
        // 上层文本(覆盖在图片上)
        Text(
            text = "Overlay Text",
            color = MaterialTheme.colorScheme.onSecondaryContainer,
            style = MaterialTheme.typography.headlineSmall
        )
    }
}

4.3 滚动布局(Scrollable)

  • LazyColumn:垂直滚动列表(仅渲染可见项,性能优)
  • LazyRow:水平滚动列表
kotlin 复制代码
@Composable
fun LazyListExample() {
    // 模拟数据
    val items = List(50) { "Item $it" }

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp), // 列表内边距
        verticalArrangement = Arrangement.spacedBy(8.dp) // 项间距
    ) {
        // 头部
        item {
            Text(
                text = "List Header",
                style = MaterialTheme.typography.headlineSmall,
                modifier = Modifier.padding(bottom = 16.dp)
            )
        }
        
        // 列表项
        items(items) { item ->
            ListItem(
                headlineContent = { Text(item) },
                leadingContent = { Icon(Icons.Default.List, contentDescription = null) },
                modifier = Modifier
                    .fillMaxWidth()
                    .background(MaterialTheme.colorScheme.surface)
                    .padding(8.dp)
            )
        }
    }
}

@Preview
@Composable
fun LazyListPreview() {
    MyComposeAppTheme {
        LazyListExample()
    }
}

五、状态管理

状态是驱动 UI 变化的核心,Compose 提供多种状态管理方式:

5.1 基础状态(remember + mutableStateOf)

remember 用于保存重组时的状态,mutableStateOf 创建可观察的状态:

kotlin 复制代码
@Composable
fun CounterExample() {
    // 计数状态:remember 确保重组时不重置,mutableStateOf 触发重组
    var count by remember { mutableStateOf(0) }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.padding(16.dp)
    ) {
        Text(text = "Count: $count", style = MaterialTheme.typography.headlineMedium)
        
        Row(spacedBy = 8.dp) {
            Button(onClick = { count-- }) { Text("-") }
            Button(onClick = { count++ }) { Text("+") }
        }
    }
}

5.2 跨组件状态(rememberSaveable)

rememberSaveable 可在配置变更(如屏幕旋转)时保留状态:

kotlin 复制代码
@Composable
fun PersistentCounter() {
    // 配置变更后仍保留状态
    var count by rememberSaveable { mutableStateOf(0) }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.padding(16.dp)
    ) {
        Text(text = "Persistent Count: $count")
        Button(onClick = { count++ }) { Text("Increment") }
    }
}

5.3 状态提升(State Hoisting)

将状态从子组件提升到父组件,实现状态共享和单向数据流:

kotlin 复制代码
// 子组件(无状态)
@Composable
fun ToggleButton(
    isToggled: Boolean,
    onToggle: () -> Unit
) {
    Button(
        onClick = onToggle,
        colors = ButtonDefaults.buttonColors(
            containerColor = if (isToggled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary
        )
    ) {
        Text(text = if (isToggled) "On" else "Off")
    }
}

// 父组件(管理状态)
@Composable
fun ToggleContainer() {
    var isToggled by remember { mutableStateOf(false) }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.padding(16.dp)
    ) {
        ToggleButton(isToggled = isToggled, onToggle = { isToggled = !isToggled })
        Text(text = "Current State: ${if (isToggled) "Active" else "Inactive"}")
    }
}

六、高级特性

6.1 动画(Animation)

Compose 内置简洁的动画 API,支持属性动画、过渡动画等:

kotlin 复制代码
@Composable
fun AnimatedBox() {
    var expanded by remember { mutableStateOf(false) }
    // 动画尺寸:从 100.dp 到 200.dp
    val size by animateDpAsState(
        targetValue = if (expanded) 200.dp else 100.dp,
        animationSpec = tween(durationMillis = 500) // 动画时长
    )

    Box(
        modifier = Modifier
            .size(size)
            .background(MaterialTheme.colorScheme.primary)
            .clickable { expanded = !expanded },
        contentAlignment = Alignment.Center
    ) {
        Text(text = if (expanded) "Expanded" else "Collapsed", color = MaterialTheme.colorScheme.onPrimary)
    }
}

6.2 主题自定义

扩展 Material Theme,自定义颜色、字体、形状:

kotlin 复制代码
// 自定义颜色方案
private val MyColorScheme = lightColorScheme(
    primary = Color(0xFF6200EE),
    secondary = Color(0xFF03DAC6),
    surface = Color.White,
    onPrimary = Color.White
)

// 自定义字体
private val MyTypography = Typography(
    headlineLarge = TextStyle(
        fontFamily = FontFamily.Default,
        fontSize = 32.sp,
        fontWeight = FontWeight.Bold
    ),
    bodyMedium = TextStyle(
        fontSize = 16.sp,
        lineHeight = 24.sp
    )
)

// 自定义主题
@Composable
fun MyCustomTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = MyColorScheme,
        typography = MyTypography,
        shapes = MaterialTheme.shapes,
        content = content
    )
}

// 使用自定义主题
@Preview
@Composable
fun CustomThemePreview() {
    MyCustomTheme {
        Column {
            Text(text = "Custom Theme Text", style = MaterialTheme.typography.headlineLarge)
            Button(onClick = {}) { Text("Custom Button") }
        }
    }
}

6.3 导航(Navigation)

集成 Jetpack Navigation 实现页面跳转:

kotlin 复制代码
// 1. 添加依赖
// implementation("androidx.navigation:navigation-compose:2.7.6")

// 2. 定义路由
sealed class Screen(val route: String) {
    object Home : Screen("home")
    object Detail : Screen("detail/{itemId}") {
        fun createRoute(itemId: Int) = "detail/$itemId"
    }
}

// 3. 导航组件
@Composable
fun AppNavHost() {
    val navController = rememberNavController()
    
    NavHost(
        navController = navController,
        startDestination = Screen.Home.route
    ) {
        composable(Screen.Home.route) {
            HomeScreen(
                onItemClick = { itemId ->
                    navController.navigate(Screen.Detail.createRoute(itemId))
                }
            )
        }
        
        composable(
            route = Screen.Detail.route,
            arguments = listOf(navArgument("itemId") { type = NavType.IntType })
        ) { backStackEntry ->
            val itemId = backStackEntry.arguments?.getInt("itemId") ?: 0
            DetailScreen(itemId = itemId, onBackClick = { navController.popBackStack() })
        }
    }
}

// 4. 页面组件
@Composable
fun HomeScreen(onItemClick: (Int) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Home Screen", style = MaterialTheme.typography.headlineLarge)
        Button(onClick = { onItemClick(123) }) { Text("Go to Detail") }
    }
}

@Composable
fun DetailScreen(itemId: Int, onBackClick: () -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Detail Screen - Item ID: $itemId", style = MaterialTheme.typography.headlineLarge)
        Button(onClick = onBackClick) { Text("Back to Home") }
    }
}

七、总结

Jetpack Compose 凭借声明式编程、简洁的 Kotlin API、高效的重组机制,大幅提升了 Android UI 开发效率。核心优势包括:

  1. 代码简洁:无需 XML,UI 逻辑与业务逻辑统一在 Kotlin 代码中;
  2. 响应式更新:基于状态驱动 UI,自动处理重组;
  3. 组件复用:可组合函数易于复用和扩展;
  4. 丰富的生态:与 Jetpack 其他组件(Navigation、ViewModel、Room)无缝集成;
  5. 实时预览:预览功能加速开发调试。

掌握 Compose 的核心概念(可组合函数、状态、重组)和布局系统,结合状态管理和动画等高级特性,可构建出高性能、现代化的 Android 界面。

相关推荐
无风之翼2 小时前
android15 休眠唤醒过程中有时候屏幕显示时间一闪而过
android·锁屏
侠***I3 小时前
基于OOA-TCN-BiGRU-Attention的鱼鹰算法优化多变量时间序列预测
kotlin
方白羽4 小时前
Android全局悬浮拖拽视图
android·app·客户端
Jerry5 小时前
Compose 高级状态和附带效应
android
2501_916007476 小时前
苹果手机iOS应用管理全指南与隐藏功能详解
android·ios·智能手机·小程序·uni-app·iphone·webview
LFly_ice7 小时前
Nest-管道
android·java·数据库
ab_dg_dp8 小时前
android bugreport 模块源码分析
android
2501_915106329 小时前
全面理解 iOS 帧率,构建从渲染到系统行为的多工具协同流畅度分析体系
android·ios·小程序·https·uni-app·iphone·webview
繁星星繁9 小时前
【Mysql】数据库基础
android·数据库·mysql