【Compose 系列】第 1 篇:认识 Compose,为什么要学它

定位:入门 / 概念启蒙 适合:完全没接触过 Compose 的 Android 开发者,或从 View 体系转过来的同学


一、先讲一个故事:装修房间的两种方式

想象你要装修一个房间,有两种干活方式。

方式 A:命令式(imperative) 你拿着清单,一步步指挥工人:

  1. 在墙上钉一个挂钩。
  2. 如果衣架挂了 3 件衣服,就把挂钩换成大号。
  3. 如果衣服超过 10 件,再装一个衣柜。

每多一种状态,你都要手写「如果......就......」的逻辑。界面和状态是两条平行线 ,你必须手动保持它们同步。这就是传统 Android 的 View + XML 开发:findViewByIdsetTextsetVisibility......状态一变,你就得记得去更新对应的控件。

方式 B:声明式(declarative) 你只写一句话:「衣架的数量 = 衣服数量 ÷ 5,衣柜的数量 = 衣服数量 ÷ 10」。工人(框架)自己会算,你从不手动搬砖。

这就是 Jetpack Compose。你只描述「界面长什么样」,框架负责「状态变化后如何更新」。这是两种思维方式的根本转变。


二、Compose 到底解决了什么痛点

痛点 View + XML 时代 Compose
状态同步 手动 setText/setVisibility,容易漏更新 状态变了界面自动重组
代码分散 XML 管布局、Kotlin 管逻辑、Adapter 管列表 一个 Kotlin 函数搞定全部
自定义控件 继承 View、写 onMeasure/onDraw,样板代码一堆 一个 @Composable 函数
列表复用 RecyclerView + Adapter + ViewHolder LazyColumn 一个函数

对小白来说,Compose 最大的好处是:学习路径短,写界面的心智负担小 。对资深开发来说,最大的好处是:消灭了 View 与数据之间那一整层容易出 bug 的胶水代码


三、第一个 Compose 程序:Hello Compose

先感受一下长什么样。下面是一个完整可运行的最小例子:

kotlin 复制代码
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.example.hellocompose.ui.theme.HelloComposeTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HelloComposeTheme {
                Surface {
                    Greeting("Compose")
                }
            }
        }
    }
}

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

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    HelloComposeTheme {
        Greeting("Compose")
    }
}

这段代码里有两个最关键的东西:

  1. @Composable:标记一个函数是「描述界面」的函数。它没有返回值,因为它不是「返回一个界面」,而是「把界面画出来」。
  2. setContent { } :Activity 的入口,从传统的 setContentView 切换到这里,后面所有内容都在这个声明式世界里运行。

四、声明式 vs 命令式:同一个计数器,两种写法

这是本篇文章最重要的案例,请仔细对比。

命令式写法(传统 View)------你要手动做三步

kotlin 复制代码
class CounterActivity : AppCompatActivity() {
    private var count = 0
    private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_counter)
        textView = findViewById(R.id.tv_count)
        findViewById<Button>(R.id.btn_add).setOnClickListener {
            count++
            textView.text = "$count"   // ① 必须手动同步
        }
    }
}

声明式写法(Compose)------只描述关系

kotlin 复制代码
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }  // 状态
    Column {
        Text("当前计数:$count")                 // 界面
        Button(onClick = { count++ }) {         // 事件只改状态
            Text("+1")
        }
    }
}

注意看:Compose 版本里没有一行「更新文本」的代码 。你只是说「文本显示 count」,然后按钮把 count 加一。框架发现 count 变了,自动重新执行 Counter,文本自己就变了。

这就是 Compose 的心智模型,一句话总结:

UI = f(state)。界面是状态的函数,状态一变,界面自动重算。


五、小白必知的 3 个名词(先混个脸熟)

  • Composable(可组合函数) :用 @Composable 标注、用来描述界面的函数。可以理解成「乐高积木块」。
  • State(状态) :界面背后会变化的数据,比如计数器里的 count。状态变了,界面才变。
  • Recomposition(重组):状态变化时,框架自动重新执行相关 Composable 的过程。这是 Compose 的发动机,下一篇专门讲。

六、资深开发者的醍醐灌顶时刻

如果你是从 View 体系过来的,请重点体会这三点:

  1. 没有 findViewById,也没有 notifyDataSetChanged。UI 更新不再是一条条命令,而是一份「由状态推导出界面」的声明。这消灭了最常见的一类 bug:状态改了但界面忘了刷新。
  2. Composable 函数会被反复调用,而且是无序的。所以它必须是「纯函数」------同样的输入产生同样的输出,不能在里面写副作用(比如直接发网络请求)。这一点很多人一开始不理解,下一篇会深入。
  3. Compose 不是「换了个语法糖的 View」,它是编译器、运行时、UI 工具链协同的一套新体系。理解了「声明式」和「重组」,后面所有知识都顺理成章。

七、常见坑

  • 把 Compose 当 View 用:还在想着「拿到这个控件引用去改它」。在 Compose 里没有控件引用,只有状态。改状态,界面自己变。
  • 在 Composable 里做耗时操作:Composable 会反复执行,如果里面发网络请求,会重复请求 N 次。耗时操作要放到「副作用」里(第 8 篇讲)。
  • 忘记 remember :下一篇会讲,现在只需记住,var count by remember { mutableStateOf(0) }remember 不能丢,丢了重组时状态会丢失。

八、动手题

把上面的计数器 demo 改造一下:加一个「-1」按钮,再显示「count 是偶数还是奇数」。改完自己跑一遍,体会「只改状态、不碰界面」的感觉。


九、学习资料

(下一篇预告:Composable 函数与「重组」机制,搞懂 Compose 的发动机。)

相关推荐
极客猴子2 小时前
iPhone实时转写软件推荐:会议录音功能真实体验
android·人工智能·飞书
达令哥2 小时前
告别 ARouter!基于 Google 官方 Navigation 3 + KSP 打造 Compose 时代的双轨制路由框架
android·前端
YF02113 小时前
Android App启动与权限管控
android
嘟哩DuliDuli3 小时前
AI 短剧生成为什么要有角色库、场景库和镜头卡
android·人工智能·安全·ai·软件工程
NINO5 小时前
深度解析 Android ANR:从标准分析流程到 NativePollOnce 疑难破局
android
阿巴斯甜5 小时前
AppFunctions 完整介绍
android
蜡台5 小时前
Jetpack Compose 从入门到精通
android·前端·kotlin·compose·jepack
toooooop85 小时前
踩坑:PHP7.2导出Excel正常,升级7.3文件损坏需修复
android·excel
mmsx6 小时前
我明明调用了 zoomToBounds,地图却总是停在别处?延迟加到 5 秒也没用,真相只有一个
android·人工智能·bug·地图