由于 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.getValue
和androidx.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,假如觉得本文对你有所协助,帮助关注、赞或者收藏三连一下,谢谢~