Android Jetpack Compose 从入门到精通

简介: Jetpack Compose 是 Google 推出的现代化 Android 声明式 UI 框架,基于 Kotlin,简化传统 XML 开发。本教程系统讲解其核心概念:可组合函数、状态管理、布局系统、Modifier 修饰符、列表滚动、主题样式、导航与动画等,助你高效构建响应式、高性能应用界面,掌握从入门到高级的最佳实践与技巧。

@TOC

概述

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 注解的函数。

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

2. 声明式 UI

传统方式(命令式):


val textView = findViewById<TextView>(R.id.text)
textView.text = "Hello"

Compose 方式(声明式):


Text(text = "Hello")

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

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

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


@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }

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

remember:在重组期间保留状态
mutableStateOf:创建可观察状态,变化时触发重组
推荐使用 ViewModel 管理 UI 状态:


@Composable
fun Counter(viewModel: CounterViewModel) {
    val count by viewModel.count.collectAsState()

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

三、基础 UI 组件

1. Text


Text(
    text = "Hello Compose",
    fontSize = 24.sp,
    fontWeight = FontWeight.Bold,
    color = Color.Blue
)

2. Image


Image(
    painter = painterResource(R.drawable.ic_logo),
    contentDescription = "Logo",
    contentScale = ContentScale.Fit
)

3. Button


Button(onClick = { /* handle click */ }) {
    Text("Click Me")
}

4. TextField


var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Enter text") }
)

四、布局系统(Layouts)

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

1. Column(垂直排列)


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

2. Row(水平排列)


Row(
    horizontalArrangement = Arrangement.SpaceBetween,
    verticalAlignment = Alignment.CenterVertically
) {
    Text("Left")
    Text("Right")
}

3. Box(层叠布局)


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

4. ConstraintLayout(高级约束)


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 的核心设计模式,用于修饰组件的外观和行为。


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(垂直滚动列表)


@Composable
fun MessageList(messages: List<String>) {
    LazyColumn {
        items(messages) { message ->
            MessageItem(message)
        }
    }
}

2. LazyRow(水平滚动)


LazyRow {
    items(10) { index ->
        Chip(text = "Item $index")
    }
}

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

七、主题与样式

1.Compose 内置 Material Design 3 主题。


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.使用主题属性:


Text(
    "Themed Text",
    style = MaterialTheme.typography.headlineMedium,
    color = MaterialTheme.colorScheme.primary
)

八、导航(Navigation)

使用 Navigation Component + Compose。

1. 添加依赖


implementation "androidx.navigation:navigation-compose:2.7.6"

2. 定义导航图


@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. 导航跳转


// 前进
navController.navigate("profile")

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

// 返回
navController.popBackStack()

九、副作用(Side Effects)

处理生命周期、数据加载等副作用。
| Effect | 用途 |
|----------------------|------------------------------|
| LaunchedEffect | 在作用域内启动协程 |
| DisposableEffect | 资源释放(如订阅) |
| rememberCoroutineScope | 获取协程作用域 |
| SideEffect | 将状态同步到非 Compose 代码 |


@Composable
fun MyScreen(viewModel: MyViewModel) {
    val coroutineScope = rememberCoroutineScope()

    LaunchedEffect(Unit) {
        viewModel.loadData()
    }

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

十、高级技巧

1. 自定义布局(Custom Layout)


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

2. 动画(Animation)


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:


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

在 Activity 中使用 Compose:


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

十一、最佳实践

必须做:

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

    避免:

  • 过度嵌套布局

  • 在 @Composable 中创建对象(除非 remember)
  • 忽略 key 参数(在 items 中)
相关文章
|
20天前
|
消息中间件 Java 调度
深入探讨进程、线程和协程之间的区别和联系
本文深入解析进程、线程与协程的核心区别与联系,涵盖资源分配、调度机制、通信方式及性能对比。结合代码示例与实际场景,阐明三者在高并发系统中的协同应用,助你掌握现代并发编程设计精髓。(239字)
132 11
|
23天前
|
前端开发 Java 测试技术
MVC、MVP 与 MVVM:Android 架构演进之路
本文深度剖析Android架构演进史:从MVC、MVP到MVVM,再到2025年主流的MVI与分层架构。结合Jetpack、Compose与Kotlin协程,揭示架构本质是对复杂性的管理,展现从“上帝类”到响应式、声明式开发的工程进化之路。
137 0
|
24天前
|
XML Android开发 数据格式
Android setContentView源码与原理分析
`setContentView` 是 Activity 显示界面的核心方法,其本质是将布局嵌入由 `PhoneWindow` 管理的 `DecorView` 中。系统首先创建包含状态栏、标题栏等的窗口模板(如 `screen_simple.xml`),再通过 `LayoutInflater` 将开发者指定的布局加载到 ID 为 `android.R.id.content` 的 `mContentParent` 容器内,最终在 `Activity` 恢复时由 `WindowManager` 将 `DecorView` 添加至窗口,触发测量与绘制流程,完成界面显示。
186 73
|
29天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
446 158
|
1月前
|
人工智能 并行计算 算法
为什么 OpenSearch 向量检索能提速 13 倍?
本文介绍在最新的 OpenSearch 实践中,引入 GPU 并行计算能力 与 NN-Descent 索引构建算法,成功将亿级数据规模下的向量索引构建速度提升至原来的 13 倍。
601 24
为什么 OpenSearch 向量检索能提速 13 倍?
|
22天前
|
Dart 开发工具 Android开发
Flutter PC 应用开发指南:从环境搭建到实战避坑
本文系统介绍如何在 Windows 平台使用 Flutter 开发 PC 应用,涵盖环境搭建、项目创建、插件兼容性、原生功能调用、签名发布、常见问题解决及性能优化等全流程,助你高效构建跨平台桌面应用,少走弯路。
408 5
|
24天前
|
安全 算法 Java
Android APK签名机制的工作原理、结构差异、安全局限与优势
本文深入解析Android APK的v1与v2签名机制,涵盖工作原理、结构差异、安全局限及最佳实践。详述身份认证、完整性保护等核心目标,对比各版本优劣,并提供签名生成、验证流程与生产环境建议,助力开发者构建安全可信的应用。
365 1
|
1月前
|
SQL 数据采集 人工智能
评估工程正成为下一轮 Agent 演进的重点
面向 RL 和在数据层(SQL 或 SPL 环境)中直接调用大模型的自动化评估实践。
947 221
|
25天前
|
缓存 安全 API
android studio Gradle 打包任务配置
本文详解Android Studio中AGP自动生成的Gradle打包任务机制,涵盖`build.gradle`核心配置:签名管理、多渠道构建、APK/AAB输出命名,以及CI/CD集成技巧。系统梳理打包流程,提供安全、高效、可追溯的发布实践方案。(238字)
259 0

热门文章

最新文章