Android Jetpack Compose 从入门到精通

文章目录

  • 概述
  • 一、为什么选择 Jetpack Compose?
      • 传统 View 系统的痛点
    • Compose 的优势
  • 二、核心概念
      1. 可组合函数(@Composable)
      1. 声明式 UI
      1. 状态与重组(State & Recomposition)
  • 三、基础 UI 组件
      1. Text
      1. Image
      1. Button
      1. TextField
  • 四、布局系统(Layouts)
      1. Column(垂直排列)
      1. Row(水平排列)
      1. Box(层叠布局)
      1. ConstraintLayout(高级约束)
  • 五、Modifier(修饰符)
    • 1.用法
    • 2.常用 Modifier
  • 六、列表与滚动
      1. LazyColumn(垂直滚动列表)
      1. LazyRow(水平滚动)
  • 七、主题与样式
    • 1.Compose 内置 Material Design 3 主题。
    • 2.使用主题属性:
  • 八、导航(Navigation)
      1. 添加依赖
      1. 定义导航图
      1. 导航跳转
  • 九、副作用(Side Effects)
  • 十、高级技巧
      1. 自定义布局(Custom Layout)
      1. 动画(Animation)
      1. 互操作(Interop)
  • 十一、最佳实践

概述

Jetpack Compose 是 Google 推出的现代化 Android 声明式 UI 工具包,使用 Kotlin 语言构建,彻底改变了传统基于 XML 的 UI 开发方式。它以 声明式函数式响应式 的方式编写界面,让 UI 开发更简洁、高效、可组合。

本教程带你从零开始,系统掌握 Compose 的核心概念与高级技巧。


一、为什么选择 Jetpack Compose?

传统 View 系统的痛点

  • XML 与 Java/Kotlin 分离,维护困难
  • 布局嵌套深,性能差
  • 代码冗长,难以复用
  • 动画实现复杂

Compose 的优势

声明式 UI :描述"UI 应该是什么样",而非"如何构建 UI"
Kotlin First :纯 Kotlin 编写,充分利用语言特性
可组合函数 :小部件自由组合,高度可复用
实时预览 :Android Studio 支持 @Preview 注解,无需运行 App
响应式 :状态变化自动更新 UI
性能优秀:智能重组(Recomposition),减少不必要的绘制


二、核心概念

1. 可组合函数(@Composable)

所有 UI 组件都是用 @Composable 注解的函数。

kotlin 复制代码
@Composable
fun Greeting(name: String) {
    Text(text = "Hello, $name!")
}

2. 声明式 UI

传统方式(命令式):

Kotlin 复制代码
val textView = findViewById<TextView>(R.id.text)
textView.text = "Hello"

Compose 方式(声明式):

Kotlin 复制代码
Text(text = "Hello")

你声明 UI 的状态,Compose 负责更新。

3. 状态与重组(State & Recomposition)

当状态变化时,Compose 会自动重新调用可组合函数(重组)。

Kotlin 复制代码
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("Clicked $count times")
    }
}

remember:在重组期间保留状态

mutableStateOf:创建可观察状态,变化时触发重组

推荐使用 ViewModel 管理 UI 状态:

Kotlin 复制代码
@Composable
fun Counter(viewModel: CounterViewModel) {
    val count by viewModel.count.collectAsState()

    Button(onClick = { viewModel.increment() }) {
        Text("Clicked $count times")
    }
}

三、基础 UI 组件

1. Text

Kotlin 复制代码
Text(
    text = "Hello Compose",
    fontSize = 24.sp,
    fontWeight = FontWeight.Bold,
    color = Color.Blue
)

2. Image

Kotlin 复制代码
Image(
    painter = painterResource(R.drawable.ic_logo),
    contentDescription = "Logo",
    contentScale = ContentScale.Fit
)

3. Button

Kotlin 复制代码
Button(onClick = { /* handle click */ }) {
    Text("Click Me")
}

4. TextField

Kotlin 复制代码
var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Enter text") }
)

四、布局系统(Layouts)

Compose 提供了强大的布局容器。

1. Column(垂直排列)

Kotlin 复制代码
Column(
    modifier = Modifier.padding(16.dp),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text("Item 1")
    Text("Item 2")
    Button(onClick = {}) { Text("OK") }
}

2. Row(水平排列)

Kotlin 复制代码
Row(
    horizontalArrangement = Arrangement.SpaceBetween,
    verticalAlignment = Alignment.CenterVertically
) {
    Text("Left")
    Text("Right")
}

3. Box(层叠布局)

Kotlin 复制代码
Box {
    Image(painter = ..., contentDescription = null)
    Text("Overlay Text", modifier = Modifier.align(Alignment.Center))
}

4. ConstraintLayout(高级约束)

Kotlin 复制代码
ConstraintLayout {
    val (text, button) = createRefs()

    Text(
        "Hello",
        modifier = Modifier.constrainAs(text) {
            top.linkTo(parent.top)
            start.linkTo(parent.start)
        }
    )

    Button(
        onClick = { },
        modifier = Modifier.constrainAs(button) {
            bottom.linkTo(parent.bottom)
            end.linkTo(parent.end)
        }
    ) {
        Text("Click")
    }
}

需添加依赖:implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

五、Modifier(修饰符)

1.用法

Modifier 是 Compose 的核心设计模式,用于修饰组件的外观和行为。

Kotlin 复制代码
Text(
    "Hello",
    modifier = Modifier
        .padding(16.dp)
        .fillMaxWidth()
        .background(Color.Gray)
        .clickable { /* handle click */ }
        .border(2.dp, Color.Black)
)

2.常用 Modifier

Modifier 作用
padding() 内边距
fillMaxWidth() / fillMaxHeight() 填充父容器
size(width, height) 设置大小
background() 背景颜色或形状
clickable { } 点击事件
border() 边框
clip() 裁剪形状(如 RoundedCornerShape(8.dp))

顺序很重要!padding().background() 与 background().padding() 效果不同。

六、列表与滚动

1. LazyColumn(垂直滚动列表)

Kotlin 复制代码
@Composable
fun MessageList(messages: List<String>) {
    LazyColumn {
        items(messages) { message ->
            MessageItem(message)
        }
    }
}

2. LazyRow(水平滚动)

Kotlin 复制代码
LazyRow {
    items(10) { index ->
        Chip(text = "Item $index")
    }
}

Lazy 前缀表示"懒加载",只渲染可见项,性能优秀。

七、主题与样式

1.Compose 内置 Material Design 3 主题。

Kotlin 复制代码
MaterialTheme(
    colorScheme = ColorScheme.Light(
        primary = Color.Blue,
        secondary = Color.Green
    ),
    typography = Typography(
        bodyLarge = TextStyle(fontSize = 18.sp)
    ),
    shapes = Shapes(
        medium = RoundedCornerShape(8.dp)
    )
) {
    // Your UI here
    Greeting("Android")
}

2.使用主题属性:

Kotlin 复制代码
Text(
    "Themed Text",
    style = MaterialTheme.typography.headlineMedium,
    color = MaterialTheme.colorScheme.primary
)

八、导航(Navigation)

使用 Navigation Component + Compose。

1. 添加依赖

Kotlin 复制代码
implementation "androidx.navigation:navigation-compose:2.7.6"

2. 定义导航图

Kotlin 复制代码
@Composable
fun NavGraph() {
    val navController = rememberNavController()

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

3. 导航跳转

Kotlin 复制代码
// 前进
navController.navigate("profile")

// 带参数
navController.navigate("detail/123")

// 返回
navController.popBackStack()

九、副作用(Side Effects)

处理生命周期、数据加载等副作用。

Effect 用途
LaunchedEffect 在作用域内启动协程
DisposableEffect 资源释放(如订阅)
rememberCoroutineScope 获取协程作用域
SideEffect 将状态同步到非 Compose 代码
Kotlin 复制代码
@Composable
fun MyScreen(viewModel: MyViewModel) {
    val coroutineScope = rememberCoroutineScope()

    LaunchedEffect(Unit) {
        viewModel.loadData()
    }

    DisposableEffect(key1 = "connection") {
        val connection = connect()
        onDispose { connection.disconnect() }
    }
}

十、高级技巧

1. 自定义布局(Custom Layout)

Kotlin 复制代码
@Composable
fun MyCustomLayout(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        content = content,
        modifier = modifier
    ) { measurables, constraints ->
        // 手动测量和布局子项
        layout(width, height) {
            // 放置子项
        }
    }
}

2. 动画(Animation)

Kotlin 复制代码
var enabled by remember { mutableStateOf(true) }
val backgroundColor by animateColorAsState(
    targetValue = if (enabled) Color.Green else Color.Red,
    tween(durationMillis = 300)
)

Box(
    modifier = Modifier
        .size(100.dp)
        .background(backgroundColor)
        .clickable { enabled = !enabled }
)

3. 互操作(Interop)

在 Compose 中使用 View:

Kotlin 复制代码
AndroidView(
    factory = { context ->
        WebView(context).apply {
            loadUrl("https://example.com")
        }
    }
)

在 Activity 中使用 Compose:

Kotlin 复制代码
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                Greeting("Android")
            }
        }
    }
}

十一、最佳实践

必须做:

  • 使用 ViewModel 管理 UI 状态
  • 为可组合函数添加 @Preview
  • 使用 remember 缓存计算结果
  • 避免在可组合函数中执行耗时操作
  • 合理使用 Modifier 顺序

避免:

  • 过度嵌套布局
  • 在 @Composable 中创建对象(除非 remember)
  • 忽略 key 参数(在 items 中)
相关推荐
参宿四南河三4 小时前
Android Compose SideEffect(副作用)实例加倍详解
android·app
火柴就是我4 小时前
mmkv的 mmap 的理解
android
没有了遇见4 小时前
Android之直播宽高比和相机宽高比不支持后动态获取所支持的宽高比
android
shenshizhong5 小时前
揭开 kotlin 中协程的神秘面纱
android·kotlin
vivo高启强5 小时前
如何简单 hack agp 执行过程中的某个类
android
沐怡旸5 小时前
【底层机制】 Android ION内存分配器深度解析
android·面试
峰哥的Android进阶之路6 小时前
viewModel机制及原理总结
android jetpack
你听得到116 小时前
肝了半个月,我用 Flutter 写了个功能强大的图片编辑器,告别image_cropper
android·前端·flutter
KevinWang_6 小时前
Android 原生 app 和 WebView 如何交互?
android
用户69371750013846 小时前
Android Studio中Gradle、AGP、Java 版本关系:不再被构建折磨!
android·android studio