由于 Compose 是声明式工具集,因此更新它的仅有办法是经过新参数调用同一可组合项。这些参数是界面状况的表现形式。每当状况更新时,都会发生重组。

本篇文章将从导图中五方面分别介绍State的相关概念和用法

简介

Compose是一种新式声明性界面工具包,它和咱们之前一向触摸的View系统完全不同,比如之前咱们想更新TextView显现文字,能够直接运用TextView.setText()来改动界面上显现的案牍,而在Compose中,现已不支持这种更新方法,取而代之的是更新这个可组合项引用的State值,这样就会触发可组合项的重组事件,重组之后可组合项会获取到State最新的值并显现在界面上,下方图片便是Compose中可组合项的生命周期:进入组合 -> 履行0次或多次重组 -> 最后是退出组合。

Compose中选用的是State来作用于可组合项中值的读取和更改,在值更改(与更改前值不同)之后就会触发可组合项的重组,然后到达界面刷新的机制。

remember{}

remember{}能够将目标存储在内存傍边,在第一次组合的时分将从remember供给的值存储到组合项中,并在重组期间回来最新存储的值。

上面咱们运用remember{ mutableStateOf("init") }创立了一个可变的State,然后在按钮点击之后改动它的值,终究会在Text中呈现出来,这里需求留意的一点便是经过= remember{}这种方法创立的结果是state目标,在引用或者修正其值时需求调用state.value,下面还有介绍两种不同的方法来创立state,原理都是共同仅仅回来的目标不同而已。

接着咱们再来看看别的两种方法是怎么运用state

  • by remember{}经过托付方法进行创立state,此方法回来的目标为state的泛型值
  • (value, changeValue) = remember{}经过解构方法进行创立state,此方法第一个参数为回来的具体值,第二个参数为Lambda表达式,可直接修正状况值

这里也有一点需求咱们留意,便是第二种托付方法创立的目标假如需求进行修正,就得运用var来修饰,而且需求额定导入两个包androidx.compose.runtime.getValueandroidx.compose.runtime.setValue,不然AS会一向爆红提示。

经过上面的代码示例想必咱们都现已了解了怎么去运用remember{}方法去创立和运用state,到这停止咱们不妨将手机屏幕旋转一下,看看更新后的state值是什么样,在末节开头的时分说到,remember{}方法是将值存到内存傍边,它并不能在装备更改后依然保存最新的值,而是会恢复成初始值,假如遇到这种状况,咱们就需求运用别的一种,那便是rememberSaveable{}它会将值保存到Bundle中,即便在屏幕旋转等装备更改之后也会取到最新的值,并不会丢掉。具体用法这里就不再多做演示,咱们能够自行体验一下。

LiveData.obseverAsState()

LiveData咱们触摸的比较早了,之前也写过一篇文章简略介绍了它的运用和源码,它是一种可调查的数据存储器类,一般结合ViewModel运用,下面咱们就经过代码来看下在Compose种怎么运用它来转换成State

运用LiveData.observeAsState()前需求增加额定的依赖:androidx.compose.runtime:runtime-livedata:1.4.3,它能够之前将LiveData转换成State,这样咱们在引用LiveData值的时分就能够直接引用State的值了,修正值依然能够直接修正LiveData的值,Compose会主动呼应修正的改变。

其内部完成也是十分简略,选用DisposableEffect副作用机制,内部增加LiveData的调查者,将调查到的值赋予state,然后在onDispose{}种撤销调查者,经过源码能够看出,这里是绑定了生命周期的,在onDestroy()时会触发onDispose{},所以在运用这种方法的状况下,咱们不用忧虑会产生内存走漏问题,内部现已帮咱们处理过了,下面是源码咱们能够自行消化下。

Flow.collectAsState()

Flow是Kotlin种一种数据流模型,它的原理就相似水流管道,上游发射下游接纳,关于Flow也是写过两片文章分别介绍了根本的运用和操作符大全,假如还没有触摸过的小伙伴能够先看下前面两片文章,熟悉下怎么简略运用,下面咱们直接来看下在Compose种怎么运用Flow

图片代码中咱们选用的是collectAsState()Flow转换成State目标,读取其值是和LiveData一样,直接读取State的值,修正值时直接更新Flow的值。

这里的collectAsState()不引荐咱们运用,因为它没有绑定生命周期,它内部是直接collect{}收集流的值,然后转换成State目标,并没有考虑到生命周期的问题,官方供给了别的一种方法协助咱们将Flow转换成State,也便是collectAsStateWithLifecycle(),这种方法选用了lifecycle.repeatOnLifecycle(){}来绑定生命周期,而且咱们能够自界说在哪一时刻开始收集数据。

此办法有四个参数:

  • initalValue能够界说初始值
  • lifecycle用于办理生命周期,在Compose种能够经过LocalLifecycleOwner.current获取到当时的生命周期办理者
  • minActiveState此参数便是界说最小在哪个周期开始收集流的值
  • context这个便是协程的上下文,用于启动协程,默以为EmptyCoroutineContext

内部选用的是produceState()方法,这里具体用法会在文章接下来具体介绍,它便是将咱们所需求的调查状况转换成State目标,这样就能够供Compose呼应此状况。

produceState

produceState是Compose供给的一种创立State的方法,它能够协助咱们自在的生成State目标

这是最简略的一种方法,只要两个参数:

  • initialValue供给一个初始值
  • producer()它是一个挂起函数,咱们能够在其内部运用协程而且供给State的值

下面咱们经过此方法来模仿一个定时器的完成,倒计时60s,每秒更新下Text文字

完成进程也是十分的简略,在producer中经过协程的delay模仿延时1s的效果,然后经过this.value来更新State的值。具体效果见下方GIF

到这4种方法就介绍完了,除了produceState之外其它的三种根本上和咱们项目的选型相关,假如项目现已选用了Kotlin的协程,那咱们能够直接选用Flow的方法,目前现已完善的挺全面了,而且操作符也是应有尽有,咱们能够按需选择~

关于我

我是Taonce,假如觉得本文对你有所协助,帮助关注、赞或者收藏三连一下,谢谢~