一、需求
在顯示界面中裳扯,數(shù)據(jù)變動抛丽,界面刷新是非常常見的操作,所以使用compose該如何實現(xiàn)呢饰豺?
二亿鲜、remember、mutableStateOf的使用
我們可以借助標(biāo)題的兩個概念 remember冤吨、mutableStateOf來完成蒿柳。這里先不寫定義,定義看完也不是很明白漩蟆,從例子中去學(xué)習(xí)垒探,先看段code:
@Composable
fun AutoIncrementTest1() {
var count = 0
Row(
modifier = Modifier.padding(20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "$count",
Modifier.padding(horizontal = 15.dp)
)
Button(onClick = { count++ }) {
Text(text = "auto-increment ")
}
}
}
這段代碼是顯示一個Text和一個Button,點擊Button后怠李,count變量自增圾叼,然后在Text中顯示出來。
但是實際測試的時候捺癞,點擊按鈕Text顯示數(shù)字是不會變化的夷蚊,原因是 Compose 并未跟蹤此變量更改。也就是說髓介,這個變量不會觸發(fā)界面的刷新惕鼓。
為了解決上面的問題就可以使用 mutableStateOf 函數(shù),來看下修改后的代碼:
State 和 MutableState 是兩個接口唐础,它們具有特定的值箱歧,每當(dāng)該值發(fā)生變化時夫否,它們就會觸發(fā)界面更新(重組)。
setContent {
ComposeTestTheme {
Surface(
color = MaterialTheme.colors.background,
) {
AutoIncrementTest2()
}
}
}
@Composable
fun AutoIncrementTest2() {
var count = mutableStateOf(0)
Row(
modifier = Modifier.padding(20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "${count.value}",
Modifier.padding(horizontal = 15.dp)
)
//用到的時候需要.value獲取
Button(onClick = { count.value++ }) {
Text(text = "auto-increment ")
}
}
}
我們把變量改成使用mutableStateOf函數(shù)叫胁,但是我點擊按鈕凰慈,Text的顯示依然不會改變,為啥呢驼鹅?
原因是在count改動的時候微谓,Surface接收的這個Composable函數(shù)就會重繪,即將這個AutoIncrementTest2函數(shù)從頭調(diào)用一遍输钩,每次調(diào)用時候豺型,走到第一行語句,count就又賦值為0买乃,所以看起來就是沒有改變姻氨,依然是0。
在這種情況下剪验,假如還想記住上一次變量值肴焊,就要用到remember,來看下修改后的代碼:
setContent {
ComposeTestTheme {
Surface(
color = MaterialTheme.colors.background,
) {
AutoIncrementTest2()
}
}
}
@Composable
fun AutoIncrementTest3() {
var count = remember {
mutableStateOf(0);
}
Row(
modifier = Modifier.padding(20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "${count.value}",
Modifier.padding(horizontal = 15.dp)
)
//用到的時候需要.value獲取
Button(onClick = { count.value++ }) {
Text(text = "auto-increment ")
}
}
}
這時候功戚,在點擊按鈕的時候娶眷,Text上顯示的就是自增的數(shù)字。
您可以將 remember 視為一種在組合中存儲單個對象的機制啸臀,就像私有 val 屬性在對象中執(zhí)行的操作一樣届宠。
當(dāng)然我們還可以優(yōu)化下,上面每次使用count的時候乘粒,都需要用.value來獲取豌注,這里再引入一個關(guān)鍵字by,修改后的代碼如下:
setContent {
ComposeTestTheme {
Surface(
color = MaterialTheme.colors.background,
) {
AutoIncrementTest2()
}
}
}
@Composable
fun AutoIncrementTest3() {
var count by remember {
mutableStateOf(0);
}
Row(
modifier = Modifier.padding(20.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "${count}",
Modifier.padding(horizontal = 15.dp)
)
Button(onClick = { count++ }) {
Text(text = "auto-increment ")
}
}
}
使用by實現(xiàn)了屬性委托灯萍,就是屬性的 set轧铁、get 的操作交給另一個對象器完成。我們可以間接讀取 count 并將其設(shè)置為可變竟稳,而無需每次都顯式引用 MutableState 的 value 屬性属桦。
總結(jié):
mutableStateOf: 表明某個變量是有狀態(tài)的,對變量進行監(jiān)聽他爸,當(dāng)狀態(tài)改變時聂宾,可觸發(fā)重繪。
remember :記錄變量的值诊笤,使得下次繪制執(zhí)行的時候系谐,不會再次進行初始化。
三、rememberSaveable 的使用
remember 函數(shù)僅在可組合項包含在組合中時起作用纪他。旋轉(zhuǎn)屏幕后鄙煤,整個 activity 都會重啟,所有狀態(tài)都將丟失茶袒。當(dāng)發(fā)生任何配置更改或者進程終止時梯刚,也會出現(xiàn)這種情況。
可以使用 rememberSaveable薪寓,而不使用 remember亡资。這會保存每個在配置更改(如旋轉(zhuǎn))和進程終止后保留下來的狀態(tài)。
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) }
運行應(yīng)用向叉,旋轉(zhuǎn)屏幕锥腻,更改為深色模式,或者終止進程母谎。除非您之前退出了應(yīng)用瘦黑,否則系統(tǒng)不會顯示初始配置屏幕。
————————————————
版權(quán)聲明:本文為CSDN博主「孔小樂」的原創(chuàng)文章奇唤,遵循CC 4.0 BY-SA版權(quán)協(xié)議幸斥,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/kongqwesd12/article/details/132556890