Jorgen's blog Jorgen's blog
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

jorgen

Love it, make mistakes, learn, keep grinding.
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Capacitor浅析
  • ADB调试
  • mlkit
  • face detection
  • Android中的Kotlin协程:告别回调地狱
  • Android性能优化实践与技巧
  • Android Jetpack Compose入门:构建现代UI的全新方式
  • Android Jetpack Compose入门与实践 - 构建现代Android UI
    • 前言
    • 什么是Jetpack Compose?
      • 声明式UI vs 命令式UI
      • Compose的优势
    • 环境搭建
      • 添加依赖
      • 配置AndroidManifest.xml
      • 启用Compose
    • 基础UI组件
      • Text组件
      • Button组件
      • Image组件
      • Column、Row和Box
    • 状态管理
      • remember和mutableStateOf
      • collectAsState
      • rememberSaveable
    • 布局系统
      • ConstraintLayout
      • LazyColumn和LazyRow
      • 自定义布局
    • 主题和样式
      • 定义主题
      • 自定义颜色
      • 自定义字体
    • 实战案例:天气应用
      • 定义数据模型
      • 创建WeatherCard组件
      • 创建主屏幕
      • ViewModel实现
    • 总结与展望
    • 未来展望
  • Android Jetpack Compose入门指南 - 构建现代UI的全新方式
  • Android Jetpack与架构组件-构建现代化应用
  • Android Jetpack架构组件:ViewModel与LiveData实战指南
  • Android Jetpack组件:构建现代Android应用的核心利器
  • Android Jetpack组件详解:构建现代化应用的核心
  • Android数据绑定与MVVM架构-构建现代化应用
  • Android架构组件:构建现代化应用的基石
  • Android架构组件与Jetpack-构建现代化应用的基石
  • Android架构组件与Jetpack-构建现代化应用的基础
  • Android架构设计之MVVM模式实战指南
  • 拥抱未来:Android Jetpack Compose入门指南
  • Android权限管理完全指南-从基础到实践
  • Android测试指南-从单元测试到UI测试的实践之路
  • Android依赖注入实战:从Dagger到Hilt的进化之路
  • Android网络编程完全指南-从HTTP到Retrofit的实践之路
  • Android数据持久化完全指南-从SharedPreferences到Room数据库
  • Android多线程与并发处理完全指南-从Thread到协程的进阶之路
  • Android应用打包与发布全流程指南-从签名到上架的实战之路
  • Android安全完全指南-从基础防护到高级加密的实战之路
  • android
Jorgen
2023-11-15
目录

Android Jetpack Compose入门与实践 - 构建现代Android UI

# 前言

作为一名Android开发者,你是否曾经被XML布局的繁琐和复杂性所困扰?是否厌倦了findViewById和频繁的UI更新操作?🤔

好消息是,Google推出了Jetpack Compose,这是一套现代化的Android UI工具包,它采用声明式编程范式,彻底改变了我们构建用户界面的方式。在本文中,我将带你走进Jetpack Compose的世界,从入门到实践,一起探索构建现代Android UI的新方式!

提示

"Compose不是要取代View系统,而是提供一种更现代、更高效的方式来构建Android UI。它将与现有的View系统共存,并逐渐成为Android UI开发的主流选择。"

# 什么是Jetpack Compose?

Jetpack Compose是Google推出的一个现代化的Android UI工具包,它使用声明式编程范式来构建原生UI。与传统的命令式UI编程不同,Compose允许你通过描述UI在特定状态下的外观来构建界面,而不是通过命令式地操作UI元素。

# 声明式UI vs 命令式UI

命令式UI(传统方式):

// 需要手动操作UI元素
val textView = findViewById<TextView>(R.id.my_text)
textView.text = "Hello World"
textView.setTextColor(Color.RED)
1
2
3
4

声明式UI(Compose方式):

// 只需描述UI在特定状态下的外观
Text(
    text = "Hello World",
    color = Color.Red
)
1
2
3
4
5

# Compose的优势

  1. 更少的代码:减少样板代码,提高开发效率
  2. 直观的状态管理:状态变化自动触发UI更新
  3. 强大的工具支持:实时预览、热重载等功能
  4. 与Kotlin完美融合:充分利用Kotlin的语言特性
  5. 统一的设计系统:Material Design 3支持

# 环境搭建

要开始使用Jetpack Compose,首先需要在项目中添加相关依赖。

# 添加依赖

在app模块的build.gradle.kts文件中添加:

dependencies {
    // Compose核心库
    implementation("androidx.compose.ui:ui:1.5.0")
    implementation("androidx.compose.material:material:1.5.0")
    implementation("androidx.compose.ui:ui-tooling-preview:1.5.0")
    
    // 活动和ViewModel支持
    implementation("androidx.activity:activity-compose:1.7.1")
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
    
    // 工具支持
    debugImplementation("androidx.compose.ui:ui-tooling:1.5.0")
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 配置AndroidManifest.xml

确保Activity使用ComponentActivity:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:theme="@style/Theme.MyApplication">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
1
2
3
4
5
6
7
8
9

# 启用Compose

在MainActivity中设置Compose内容:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting(name = "Android")
                }
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 基础UI组件

Compose提供了丰富的UI组件,让我们从最基础的开始学习。

# Text组件

Text(
    text = "Hello Compose!",
    color = Color.Blue,
    fontSize = 24.sp,
    fontWeight = FontWeight.Bold,
    modifier = Modifier.padding(16.dp)
)
1
2
3
4
5
6
7

# Button组件

Button(
    onClick = {
        // 按钮点击事件
        Log.d("Compose", "Button clicked!")
    },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.primary,
        contentColor = Color.White
    )
) {
    Text(text = "Click Me")
}
1
2
3
4
5
6
7
8
9
10
11
12

# Image组件

Image(
    painter = painterResource(id = R.drawable.ic_launcher_foreground),
    contentDescription = "App Logo",
    modifier = Modifier.size(100.dp),
    contentScale = ContentScale.Crop
)
1
2
3
4
5
6

# Column、Row和Box

这些是Compose中最基础的布局组件:

Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text("Item 1")
    Text("Item 2")
    Text("Item 3")
}

Row(
    modifier = Modifier.fillMaxWidth(),
    horizontalArrangement = Arrangement.SpaceEvenly,
    verticalAlignment = Alignment.CenterVertically
) {
    Text("Left")
    Text("Center")
    Text("Right")
}

Box(
    modifier = Modifier.size(200.dp),
    contentAlignment = Alignment.Center
) {
    Text("I'm in a Box")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 状态管理

状态管理是Compose的核心概念之一。在Compose中,当状态改变时,UI会自动重新渲染。

# remember和mutableStateOf

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "Count: $count")
        
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# collectAsState

对于Flow,可以使用collectAsState来收集状态:

@Composable
fun UserProfile(userId: String) {
    val user by viewModel.getUser(userId).collectAsState()
    
    if (user == null) {
        CircularProgressIndicator()
    } else {
        Text(text = "Welcome, ${user.name}!")
    }
}
1
2
3
4
5
6
7
8
9
10

# rememberSaveable

remember只在组合期间保持状态,而rememberSaveable会在配置更改时保持状态:

@Composable
fun RememberSaveableExample() {
    var text by rememberSaveable { mutableStateOf("") }
    
    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Enter text") }
    )
}
1
2
3
4
5
6
7
8
9
10

# 布局系统

Compose的布局系统灵活而强大,让我们深入了解一些高级布局技巧。

# ConstraintLayout

类似于传统Android的ConstraintLayout,Compose也提供了类似的功能:

ConstraintLayout(
    modifier = Modifier.fillMaxSize()
) {
    val (button, text) = createRefs()
    
    Button(
        onClick = { /* Do something */ },
        modifier = Modifier.constrainAs(button) {
            top.linkTo(parent.top, margin = 16.dp)
            start.linkTo(parent.start, margin = 16.dp)
        }
    ) {
        Text("Button")
    }
    
    Text(
        text = "Hello ConstraintLayout",
        modifier = Modifier.constrainAs(text) {
            top.linkTo(button.bottom, margin = 16.dp)
            start.linkTo(button.start)
            end.linkTo(button.end)
        }
    )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# LazyColumn和LazyRow

用于高效显示长列表:

LazyColumn(
    modifier = Modifier.fillMaxSize(),
    contentPadding = PaddingValues(16.dp),
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    items(100) { index ->
        Card(
            modifier = Modifier.fillMaxWidth(),
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
        ) {
            Text(
                text = "Item #$index",
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 自定义布局

你可以创建自己的自定义布局:

@Composable
fun StaggeredGrid(
    modifier: Modifier = Modifier,
    rows: Int = 3,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // 测量和布局逻辑
        // ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 主题和样式

Compose提供了强大的主题系统,可以轻松自定义应用的外观。

# 定义主题

@Composable
fun MyApplicationTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme = if (darkTheme) {
        DarkColorScheme
    } else {
        LightColorScheme
    }
    
    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography(),
        shapes = Shapes(),
        content = content
    )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 自定义颜色

private val LightColorScheme = lightColorScheme(
    primary = Color(0xFF6200EE),
    primaryContainer = Color(0xFFEADDFF),
    secondary = Color(0xFF03DAC5),
    background = Color(0xFFFFFBFE),
    surface = Color(0xFFFFFBFE),
    onPrimary = Color.White,
    onSecondary = Color.Black,
    onBackground = Color(xFF1C1B1F),
    onSurface = Color(xFF1C1B1F)
)
1
2
3
4
5
6
7
8
9
10
11

# 自定义字体

val Typography = Typography(
    bodyLarge = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp,
        lineHeight = 24.sp,
        letterSpacing = 0.5.sp
    ),
    titleLarge = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 22.sp,
        lineHeight = 28.sp,
        letterSpacing = 0.sp
    )
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 实战案例:天气应用

让我们通过构建一个简单的天气应用来实践Compose的知识。

# 定义数据模型

data class WeatherInfo(
    val city: String,
    val temperature: Int,
    val description: String,
    val icon: String
)
1
2
3
4
5
6

# 创建WeatherCard组件

@Composable
fun WeatherCard(
    weather: WeatherInfo,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier.fillMaxWidth(),
        elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                text = weather.city,
                style = MaterialTheme.typography.headlineMedium
            )
            
            Image(
                painter = painterResource(id = getWeatherIcon(weather.icon)),
                contentDescription = weather.description,
                modifier = Modifier.size(64.dp)
            )
            
            Text(
                text = "${weather.temperature}°C",
                style = MaterialTheme.typography.displayLarge
            )
            
            Text(
                text = weather.description,
                style = MaterialTheme.typography.bodyLarge
            )
        }
    }
}

private fun getWeatherIcon(iconName: String): Int {
    return when (iconName) {
        "sunny" -> R.drawable.ic_sunny
        "cloudy" -> R.drawable.ic_cloudy
        "rainy" -> R.drawable.ic_rainy
        else -> R.drawable.ic_default
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 创建主屏幕

@Composable
fun WeatherScreen(
    viewModel: WeatherViewModel = viewModel()
) {
    val weather by viewModel.weather.collectAsState()
    val isLoading by viewModel.isLoading.collectAsState()
    val error by viewModel.error.collectAsState()
    
    LaunchedEffect(Unit) {
        viewModel.loadWeather("Beijing")
    }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
    ) {
        when {
            isLoading -> CircularProgressIndicator(
                modifier = Modifier.align(Alignment.Center)
            )
            error != null -> Text(
                text = "Error: $error",
                color = Color.Red,
                modifier = Modifier.align(Alignment.Center)
            )
            weather != null -> WeatherCard(
                weather = weather!!,
                modifier = Modifier.align(Alignment.Center)
            )
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# ViewModel实现

class WeatherViewModel : ViewModel() {
    private val _weather = MutableStateFlow<WeatherInfo?>(null)
    val weather: StateFlow<WeatherInfo?> = _weather
    
    private val _isLoading = MutableStateFlow(false)
    val isLoading: StateFlow<Boolean> = _isLoading
    
    private val _error = MutableStateFlow<String?>(null)
    val error: StateFlow<String?> = _error
    
    fun loadWeather(city: String) {
        viewModelScope.launch {
            _isLoading.value = true
            _error.value = null
            
            try {
                // 模拟网络请求
                delay(1000)
                
                // 模拟成功响应
                _weather.value = WeatherInfo(
                    city = city,
                    temperature = 22,
                    description = "Sunny",
                    icon = "sunny"
                )
            } catch (e: Exception) {
                _error.value = e.message
            } finally {
                _isLoading.value = false
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 总结与展望

通过本文,我们了解了Jetpack Compose的基础知识和实践技巧。从环境搭建到基础UI组件,从状态管理到布局系统,再到主题定制和实战案例,我们一步步走进了Compose的世界。

THEOREM

Compose的核心思想是"声明式UI",即通过描述UI在特定状态下的外观来构建界面,而不是通过命令式地操作UI元素。这种范式使得代码更简洁、更易于维护,同时也更符合现代软件开发的理念。

"Jetpack Compose不仅仅是一个UI工具,它代表了Android开发的未来方向。随着Compose的不断成熟和完善,它将成为Android开发不可或缺的一部分。"

对于开发者来说,现在正是学习Compose的最佳时机。虽然View系统仍然会存在很长一段时间,但Compose已经成为Android开发的重要趋势。掌握Compose,不仅能提高开发效率,还能让你在未来的Android开发中保持竞争力。

# 未来展望

Jetpack Compose仍在快速发展中,未来我们可以期待:

  1. 更丰富的组件库:更多预定义的组件和布局
  2. 更好的性能:更高效的渲染机制
  3. 更强大的工具支持:更好的IDE集成和调试工具
  4. 跨平台支持:Compose可能扩展到iOS、Web和桌面平台
  5. 与Kotlin Multiplatform的深度集成:实现真正的跨平台UI开发

让我们一起拥抱Compose,构建更美好的Android应用吧!🚀


希望这篇博客能帮助你入门Jetpack Compose!如果你有任何问题或建议,欢迎在评论区留言讨论。👇

#Jetpack Compose#Android UI#声明式UI#现代 Android 开发
上次更新: 2026/01/28, 14:21:05
Android Jetpack Compose入门:构建现代UI的全新方式
Android Jetpack Compose入门指南 - 构建现代UI的全新方式

← Android Jetpack Compose入门:构建现代UI的全新方式 Android Jetpack Compose入门指南 - 构建现代UI的全新方式→

最近更新
01
LLM
01-30
02
intro
01-30
03
intro
01-30
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jorgen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式