在过去的很长一段时间里,Android 开发者们都在忍受着 XML 布局带来的折磨。我们需要在 XML 中定义视图,然后在 Java/Kotlin 代码中通过 findViewById 或者 ViewBinding 来获取视图实例,再手动更新它们的状态。这种命令式的 UI 编写方式不仅割裂了逻辑与 UI,还经常导致繁琐的代码和难以维护的状态。
为了解决这些痛点,Google 推出了 Jetpack Compose。这是一种用于构建原生 Android UI 的现代工具包,它完全采用 Kotlin 编写,并且拥抱了声明式编程范式。这篇文章将带你走进 Compose 的世界,看看如何用 Kotlin 优雅地编写 UI。
背景与概念
在深入了解 Compose 之前,我们需要先明白什么是“声明式 UI”,以及它与我们熟知的“命令式 UI”有什么区别。
- 命令式(传统 XML):你需要一步步告诉系统“怎么做”。比如:找到这个 TextView,把它的文本设置成 “Hello”,把它的颜色设置成红色。
- 声明式(Compose):你只需要描述 UI “是什么样子”。比如:我需要一个红色的文本,内容是 “Hello”。当状态发生改变时,UI 会自动刷新(重组)来匹配新的状态。
这种思想其实在前端框架(如 React、Vue)和跨平台框架(如 Flutter)中早已大放异彩,如今 Android 原生开发也终于迎来了这个特性!(/▽\)
核心:@Composable 函数
在 Compose 中,UI 组件其实就是一个个带有 @Composable 注解的 Kotlin 函数。我们不再需要继承 View 类,也不需要编写庞大的 XML 文件。
来看一个最简单的例子:
1 | import androidx.compose.material3.Text |
在这个函数中,我们接收了一个 name 参数,并调用了内置的 Text 组件来显示文本。就是这么简单!只要加了 @Composable 注解,这个普通函数就变成了一个 UI 描述符。
基础布局
在传统的 XML 中,我们有 LinearLayout、RelativeLayout、FrameLayout 等。在 Compose 中,布局变得更加直观和简单,主要依赖于三个核心组件:
1. Column (垂直布局)
相当于 LinearLayout 设置了 orientation="vertical"。
1 |
|
2. Row (水平布局)
相当于 LinearLayout 设置了 orientation="horizontal"。
1 |
|
3. Box (堆叠布局)
相当于 FrameLayout,里面的元素会像千层饼一样堆叠起来。
1 |
|
状态管理与重组
在 Compose 中,UI 是无状态的,它只负责根据当前的数据渲染画面。当数据发生变化时,Compose 会智能地找出依赖这些数据的 @Composable 函数,并重新执行它们,这个过程叫做**重组 (Recomposition)**。
要想让 Compose 监听到状态变化,我们需要使用 State。下面是一个经典的计数器例子:
1 | import androidx.compose.material3.Button |
在这个例子中:
mutableStateOf(0)创建了一个可变的状态,初始值为 0。remember确保在发生重组时,count的值不会被重置,而是被安全地“记住”了。- 当用户点击
Button时,count++触发状态改变,Compose 会自动重新调用依赖了count的Text组件,从而更新屏幕上的数字。你完全不需要去手动调用类似于textView.setText()的方法!
Modifier:魔法修饰符
在 XML 中,我们通过属性来设置大小、边距、背景颜色等(如 android:layout_width)。而在 Compose 中,这一切都交给了 Modifier。
Modifier 是一种链式调用的修饰符,可以用来改变组件的外观和行为:
1 |
|
注意:Modifier 的调用顺序是非常重要的!先设置 padding 再设置 background,和先设置 background 再设置 padding,两者呈现出来的视觉效果是完全不同的。
总结
Jetpack Compose 彻底颠覆了 Android 原有的 UI 开发模式。通过 Kotlin 的强大语言特性,它让 UI 开发变得更加简洁、直观和高效。告别了冗长的 XML,告别了繁琐的视图绑定,声明式 UI 无疑是 Android 开发的未来。
如果你还在犹豫是否要学习 Compose,那么现在就是最好的时机
说些什么吧!