大话Compose筑基(1)

690 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

前言

网上已有很多很多Compose的各种文章了,为啥我还想写一个Compose系列的文章呢?原因很简单,Compose不好学,并且我发现真正引导入门的文章其实并不多,大部分质量高的教程和文章都适合有一定基础或者已经入门了Compose的人去阅读学习,往往没有什么基础的xdm看到这些文章就直接从入门到放弃了。Compose筑基系列旨在用简单易懂的语言和简洁深刻的例子让大家对Compose不再排斥恐惧,而是让大家自愿地想去学习了解它。不管你是第一次学习还是第n次重学Compose,我都希望这个系列是你的最后一个入门学习了。

学还是不学,这是个问题

相信近几年搞Android开发的兄弟们都有种学不动的幸福感了。Kotlin语言、Androidx库、Jetpack库包等接踵而至,它们每一个都可以说是颠覆的存在。出来了学呗,从官方MVP架构学到MVVM,又从MVVM学到MVI。里面涉及到的新东西实在太多太多,我个人感受改变最大的就是界面的实现方式的改变。从鼓励viewbinding代替findViewbyId,黄油刀等,又到鼓励用databinding来进一步精简v层代码和解耦,如今再到声明性界面工具包Compose。说明什么呢?我认为理由很简单,传统的命令式势必要被更灵活强大的声明性替代。简单说就是Compose出现之前的所有的实现方式不够好用或者没啥大用。如果你觉得之前的xml+viewbinding+databinding实现方式没有啥不好的,那么真的可以不学,因为Compose真的很颠覆,并且颠覆的不仅是界面的实现方式,也会颠覆我们对之前Android项目架构的认识。

学前准备-抽象到具象

能看到这里大概率证明你是更愿意用MAD技术去开发的Android开发者了。欢迎你的加入,我们接着下面的继续

学习一个新的技术,大家往往都会选择官方文档去学习。但是我第一次看Compose的官方文档时,给我的感觉是每个字我都认识,但是看完还是不知道说了啥。不是说官方文档不好,也不是翻译的不准确,主要还是因为文档的作者是以一个上帝视角去写的。导致很多内容都是抽象的,如果我们本身没有接触过compose,确实就会造成看了像没看一样的窘境。不过随着我们在学习compose的过程中,还是推荐大家时不时去看看官方文档,每次看看都会有不同的收获的。为了帮助大家对抽象概念的理解,我们在入门的时候可以把compose实现界面的方式具化成一个拼图的过程。

组合

假设手机的屏幕是一个放置拼图的框框。每一个可组合函数就是一块拼图。那么我们在框子里面放一块拼图就是一个拼图组合出来的页面,放n个拼图就是n个拼图组成的页面。

先看下面简单的例子

@Composable
fun Puzzle1() {
    Box(modifier = Modifier.fillMaxSize().background(Color.Red), contentAlignment = Alignment.Center) {
        Text(
            modifier = Modifier.background(Color.Green),
            text = "内嵌拼图",
            textAlign = TextAlign.Center,
        )
    }
}

@Composable注释Puzzle1函数,把函数变成了可组合函数,也就是变成了一个拼图。Puzzle1拼图里面再放一个填充整个页面的Box红色背景的拼图,Box拼图里面再放一个居中绿色背景的Text拼图。到此这个拼图组合完毕,运行后页面显示如图:

状态

看完上面的例子可能有人会说,这个也没啥啊,我不用Compose也完全可以实现啊,为啥还要用Compose呢?先不急哈,我们后面一步一步来找到答案。我们先了解一下Compose的状态(State)。

引用官方文档内对状态的解释--由于 Compose 是声明式工具集,因此更新它的唯一方法是通过新参数调用同一可组合项。这些参数是界面状态的表现形式。每当状态更新时,都会发生重组。来看下面的代码

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, true)
        setContent {
            var name by remember {
                mutableStateOf("Hello")
            }
            Text(name)
            LaunchedEffect(key1 = Unit, block = {
                delay(3000)
                name = "Hello World"
            })
        }
}

页面显示Hello的Text,3秒后更新成Hello World。name是Text可组合函数的参数,同时也是通过mutableStateOf()构建出来的状态。然后此name状态在3秒后值被修改了(状态改变了),于是重组作用域观察到了改变,触发了重组,最终刷新了页面。这里可能有兄弟们对重组作用域和重组不太了解。不要紧,在这里只用先知道这个流程就行,后面马上会说到它们俩的。

  • 创建可被观察的状态几种方式
    1.直接创建State:mutableStateOf
    2.Flow转State:collectAsStateWithLifecycle()
    3.LiveData转State: observeAsState()
    4.RxJava2转State: subscribeAsState()
    5.RxJava3转State: subscribeAsState()
    6.自定义可观察类转State:produceState()

以上几种方式我们会在后面的例子中慢慢给大家展示和说明

小结

这一章带大家简单认识了组合和状态。通过拼图具化了Compose的抽象概念,也通过几个例子知道了可以通过状态的改变来实现页面的动态更新。而实现更新的方式就是重组.下一章我们就开始讲重组重组作用域

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情