首页 Android 正文
  • 本文约5132字,阅读需26分钟
  • 40
  • 0

Android Jetpack Compose 从入门到精通

摘要

概述 Jetpack Compose 是 Google 推出的现代化 Android 声明式 UI 工具包,使用 Kotlin 语言构建,彻底改变了传统基于 XML 的 UI 开发方式。它以 声明式、函数式 和 响应式 的方式编写界面,让 UI 开发更简洁、高效、可组合。 本教程带你从零开始,系统掌握 Compose 的核心概念与高级技巧。 一、为什么选择 ...

概述

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") }
}
  1. 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 中)

扫描二维码,在手机上阅读
文章目录


    扫描二维码,在手机上阅读
      评论
      友情链接