Compose基础入门

第1课:Compose基础入门

🎯 本节课目标

  • 理解什么是Compose
  • 学会写第一个Compose函数
  • 理解@Composable注解
  • 理解Modifier的作用

📖 第一部分:什么是Compose?

传统方式(XML布局)vs Compose方式

传统方式(XML + Java/Kotlin):

xml 复制代码
<!-- activity_main.xml -->
<LinearLayout>
    <TextView android:text="Hello" />
    <Button android:text="Click Me" />
</LinearLayout>

Compose方式(纯Kotlin代码):

kotlin 复制代码
@Composable
fun MainScreen() {
    Column {
        Text("Hello")
        Button(onClick = { }) {
            Text("Click Me")
        }
    }
}

关键区别:

  • ✅ 代码即UI,不需要XML文件
  • ✅ 类型安全,编译时检查
  • ✅ 函数式编程,更简洁
  • ✅ 状态变化时自动更新UI

🔍 第二部分:看一个真实的例子

让我们看项目中最简单的一个Screen:

kotlin:30:85:app/src/main/java/com/volvocars/telephony/china/ui/calllog/CallLogScreen.kt 复制代码
@Composable
fun CallLogScreen(
    modifier: Modifier = Modifier,
    callLogVM: CallLogViewModel = koinViewModel(),
    contactsVM: ContactsViewModel = koinViewModel(),
    callVM: CallViewModel = koinViewModel()
) {
    val uiState by callLogVM.uiState.collectAsStateWithLifecycle()

    LaunchedEffect(Unit) {
        callLogScreen.sendIntent(CallLogIntent.FetchCallLog)
        contactsVM.sendIntent(ContactsIntent.FetchContacts)
    }

    Box(
        modifier = modifier,
        contentAlignment = Alignment.TopStart
    ) {
        when (uiState.loadState) {
            is LoadState.Idle -> {
            }

            is LoadState.Loading -> {
                Loading(modifier = Modifier.fillMaxSize(), text = stringResource(id = R.string.sync_data))
            }

            is LoadState.Empty -> {
                DefaultStatusPageScreen(
                    modifier = Modifier.fillMaxSize(),
                    status = DefaultPageScreenStatus.NoCallLog,
                    btnClick = {
                        callLogVM.sendIntent(CallLogIntent.FetchCallLog)
                    }
                )
            }

            is LoadState.LoadSuccess -> {
                LazyColumn(
                    modifier = Modifier.padding(start = appDimens.dev.dp24 + appDimens.spacing.spacing4xLarge),
                    verticalArrangement = Arrangement.spacedBy(appDimens.spacing.spacingXSmall)
                ) {
                    items(uiState.data ?: emptyList()) { data ->
                        CallContactListItem(
                            callContactEntry = data,
                            onClick = {
                                callVM.sendIntent(CallIntent.PlaceCall(data.phoneNumbers()?.firstOrNull()?.number))
                            }
                        )
                    }
                }
            }

            is LoadState.LoadError -> {
            }
        }
    }
}

🎓 第三部分:逐步讲解

1. @Composable 注解

kotlin 复制代码
@Composable
fun CallLogScreen(...)

作用:

  • 告诉编译器:这是一个Compose函数
  • 这个函数可以在setContent { }中调用
  • 可以调用其他@Composable函数

规则:

  • @Composable函数只能在其他@Composable函数中调用
  • 不能在普通函数中调用
kotlin 复制代码
// ✅ 正确
@Composable
fun Parent() {
    Child()  // 可以调用
}

// ❌ 错误
fun normalFunction() {
    Child()  // 不能调用!
}

2. 函数参数

kotlin 复制代码
fun CallLogScreen(
    modifier: Modifier = Modifier,  // 样式参数
    callLogVM: CallLogViewModel = koinViewModel()  // ViewModel(暂时忽略)
)

modifier参数:

  • 几乎所有Compose组件都有modifier参数
  • 用于控制样式、大小、位置等
  • 默认值是Modifier(无效果)

默认参数:

  • = Modifier:调用时可以不传
  • = koinViewModel():会自动获取ViewModel(后面讲)

3. 第一个布局组件:Box

kotlin 复制代码
Box(
    modifier = modifier,
    contentAlignment = Alignment.TopStart
) {
    // 子组件
}

Box的作用:

  • 层叠布局(类似FrameLayout)
  • 可以叠加多个组件
  • contentAlignment:控制子组件对齐方式

对齐方式:

  • Alignment.TopStart:左上角
  • Alignment.Center:居中
  • Alignment.BottomEnd:右下角
  • 等等...

4. 条件渲染:when表达式

kotlin 复制代码
when (uiState.loadState) {
    is LoadState.Loading -> LoadingScreen()
    is LoadState.LoadSuccess -> ContentScreen()
    is LoadState.Empty -> EmptyScreen()
    is LoadState.LoadError -> ErrorScreen()
}

作用:

  • 根据状态显示不同的UI
  • 类似if-else,但更清晰
  • is关键字:类型检查

这是Compose的核心思想:

  • 状态驱动UI
  • 状态改变 → UI自动更新

💡 第四部分:动手实践

任务1:写你的第一个Compose函数

创建一个新文件,写一个最简单的Screen:

kotlin 复制代码
@Composable
fun MyFirstScreen() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text("Hello Compose!")
    }
}

解释:

  • Modifier.fillMaxSize():填满整个屏幕
  • Alignment.Center:居中显示
  • Text("Hello Compose!"):显示文本

任务2:尝试不同的对齐方式

修改contentAlignment,看看效果:

kotlin 复制代码
Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.TopStart  // 试试改成 TopCenter, BottomEnd 等
) {
    Text("Hello Compose!")
}

任务3:添加多个组件

kotlin 复制代码
@Composable
fun MyFirstScreen() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Column {  // Column:垂直排列
            Text("第一行")
            Text("第二行")
            Text("第三行")
        }
    }
}

Column的作用:

  • 垂直排列子组件
  • 类似LinearLayout(vertical)

🎯 第五部分:Modifier详解

什么是Modifier?

Modifier = 样式和布局的修饰符

kotlin 复制代码
Text(
    text = "Hello",
    modifier = Modifier
        .padding(16.dp)      // 内边距
        .background(Color.Red)  // 背景色
        .fillMaxWidth()      // 填满宽度
)

常用Modifier(先记住这几个)

Modifier 作用 示例
.fillMaxSize() 填满父容器 Modifier.fillMaxSize()
.fillMaxWidth() 填满宽度 Modifier.fillMaxWidth()
.size(100.dp) 固定大小 Modifier.size(100.dp)
.padding(16.dp) 内边距 Modifier.padding(16.dp)
.background(Color.Red) 背景色 Modifier.background(Color.Red)
.clickable { } 点击事件 Modifier.clickable { onClick() }

Modifier的链式调用

kotlin 复制代码
Modifier
    .fillMaxWidth()        // 先填满宽度
    .padding(16.dp)        // 再加内边距
    .background(Color.White)  // 再设置背景
    .clickable { }         // 最后加点击事件

重要:顺序很重要!

  • 先设置的会影响后设置的
  • 通常顺序:大小 → 间距 → 样式 → 事件

实践:给Text添加样式

kotlin 复制代码
@Composable
fun MyFirstScreen() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "Hello Compose!",
            modifier = Modifier
                .padding(20.dp)
                .background(Color.Blue)
                .padding(10.dp)  // 注意:这个padding在background外面
        )
    }
}

观察:

  • 背景色在哪里?
  • padding在哪里?
  • 试试调整顺序看看效果

📚 第六部分:常用基础组件

Text - 文本

kotlin 复制代码
Text(
    text = "Hello World",
    color = Color.Black,
    fontSize = 16.sp
)

Button - 按钮

kotlin 复制代码
Button(onClick = { 
    // 点击事件
}) {
    Text("点击我")
}

Column - 垂直布局

kotlin 复制代码
Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally  // 水平居中
) {
    Text("第一行")
    Text("第二行")
}

Row - 水平布局

kotlin 复制代码
Row(
    modifier = Modifier.fillMaxWidth(),
    horizontalArrangement = Arrangement.SpaceBetween  // 两端对齐
) {
    Text("左侧")
    Text("右侧")
}

✍️ 第七部分:综合练习

练习:创建一个简单的登录界面

kotlin 复制代码
@Composable
fun LoginScreen() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(32.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "登录",
            fontSize = 24.sp
        )
        
        Spacer(modifier = Modifier.height(32.dp))  // 间距
        
        Text(
            text = "用户名",
            modifier = Modifier.fillMaxWidth()
        )
        
        Spacer(modifier = Modifier.height(16.dp))
        
        Text(
            text = "密码",
            modifier = Modifier.fillMaxWidth()
        )
        
        Spacer(modifier = Modifier.height(32.dp))
        
        Button(
            onClick = { /* 登录 */ },
            modifier = Modifier.fillMaxWidth()
        ) {
            Text("登录")
        }
    }
}

学习点:

  1. Column垂直布局
  2. modifier链式调用
  3. Spacer添加间距
  4. fillMaxWidth()的使用

🎯 本节课总结

核心概念

  1. @Composable:标记Compose函数
  2. Modifier:样式和布局修饰符
  3. Box:层叠布局
  4. Column:垂直布局
  5. Row:水平布局

关键点

  • Compose是声明式UI:描述"是什么",而不是"怎么做"
  • 状态驱动UI:状态改变,UI自动更新
  • Modifier链式调用:顺序很重要

相关推荐
leaves falling14 小时前
C语言内存函数-
c语言·开发语言
至为芯16 小时前
IP6537至为芯支持双C口快充输出的45W降压SOC芯片
c语言·开发语言
小羊羊Python16 小时前
SoundMaze v1.0.1正式发布!
开发语言·c++
浩瀚地学16 小时前
【Java】JDK8的一些新特性
java·开发语言·经验分享·笔记·学习
l1t16 小时前
利用DeepSeek将python DLX求解数独程序格式化并改成3.x版本
开发语言·python·算法·数独
yugi98783818 小时前
基于遗传算法优化主动悬架模糊控制的Matlab实现
开发语言·matlab
moxiaoran575318 小时前
Go语言的错误处理
开发语言·后端·golang
yugi98783819 小时前
MATLAB的多层感知器(MLP)与极限学习机(ELM)实现
开发语言·matlab
Never_Satisfied19 小时前
C#获取汉字拼音字母方法总结
开发语言·c#
zh_xuan20 小时前
kotlin 密封类
开发语言·kotlin