一、需求
在顯示界面中,數(shù)據(jù)變動(dòng),界面刷新是非常常見的操作,所以使用compose該如何實(shí)現(xiàn)呢?
二、remember、mutableStateOf的使用
我們可以借助標(biāo)題的兩個(gè)概念 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 ")
}
}
}
這段代碼是顯示一個(gè)Text和一個(gè)Button,點(diǎn)擊Button后,count變量自增,然后在Text中顯示出來。
但是實(shí)際測試的時(shí)候,點(diǎn)擊按鈕Text顯示數(shù)字是不會(huì)變化的,原因是 Compose 并未跟蹤此變量更改。也就是說,這個(gè)變量不會(huì)觸發(fā)界面的刷新。
為了解決上面的問題就可以使用 mutableStateOf 函數(shù),來看下修改后的代碼:
State 和 MutableState 是兩個(gè)接口,它們具有特定的值,每當(dāng)該值發(fā)生變化時(shí),它們就會(huì)觸發(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)
)
//用到的時(shí)候需要.value獲取
Button(onClick = { count.value++ }) {
Text(text = "auto-increment ")
}
}
}
我們把變量改成使用mutableStateOf函數(shù),但是我點(diǎn)擊按鈕,Text的顯示依然不會(huì)改變,為啥呢?
原因是在count改動(dòng)的時(shí)候,Surface接收的這個(gè)Composable函數(shù)就會(huì)重繪,即將這個(gè)AutoIncrementTest2函數(shù)從頭調(diào)用一遍,每次調(diào)用時(shí)候,走到第一行語句,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)
)
//用到的時(shí)候需要.value獲取
Button(onClick = { count.value++ }) {
Text(text = "auto-increment ")
}
}
}
這時(shí)候,在點(diǎn)擊按鈕的時(shí)候,Text上顯示的就是自增的數(shù)字。
您可以將 remember 視為一種在組合中存儲(chǔ)單個(gè)對(duì)象的機(jī)制,就像私有 val 屬性在對(duì)象中執(zhí)行的操作一樣。
當(dāng)然我們還可以優(yōu)化下,上面每次使用count的時(shí)候,都需要用.value來獲取,這里再引入一個(gè)關(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實(shí)現(xiàn)了屬性委托,就是屬性的 set、get 的操作交給另一個(gè)對(duì)象器完成。我們可以間接讀取 count 并將其設(shè)置為可變,而無需每次都顯式引用 MutableState 的 value 屬性。
總結(jié):
mutableStateOf: 表明某個(gè)變量是有狀態(tài)的,對(duì)變量進(jìn)行監(jiān)聽,當(dāng)狀態(tài)改變時(shí),可觸發(fā)重繪。
remember :記錄變量的值,使得下次繪制執(zhí)行的時(shí)候,不會(huì)再次進(jìn)行初始化。
三、rememberSaveable 的使用
remember 函數(shù)僅在可組合項(xiàng)包含在組合中時(shí)起作用。旋轉(zhuǎn)屏幕后,整個(gè) activity 都會(huì)重啟,所有狀態(tài)都將丟失。當(dāng)發(fā)生任何配置更改或者進(jìn)程終止時(shí),也會(huì)出現(xiàn)這種情況。
可以使用 rememberSaveable,而不使用 remember。這會(huì)保存每個(gè)在配置更改(如旋轉(zhuǎn))和進(jìn)程終止后保留下來的狀態(tài)。
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) }
運(yùn)行應(yīng)用,旋轉(zhuǎn)屏幕,更改為深色模式,或者終止進(jìn)程。除非您之前退出了應(yīng)用,否則系統(tǒng)不會(huì)顯示初始配置屏幕。
————————————————
版權(quán)聲明:本文為CSDN博主「孔小樂」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/kongqwesd12/article/details/132556890