最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android Compose 狀態(tài)的概念及實(shí)際應(yīng)用

 更新時(shí)間:2025年10月22日 14:30:39   作者:氦客  
Android 應(yīng)用本質(zhì)上就是在“展示狀態(tài)”:比如沒(méi)網(wǎng)時(shí)顯示的提示、點(diǎn)擊按鈕時(shí)的漣漪效果、圖片上用戶添加的貼紙,本質(zhì)都是在呈現(xiàn)不同時(shí)刻的“狀態(tài)”,這篇文章主要介紹了Android Compose狀態(tài)的概念,需要的朋友可以參考下

Jetpack Compose 中的狀態(tài)

一、什么是“狀態(tài)”?

應(yīng)用里可以隨時(shí)間變化的任何值都叫“狀態(tài)”——這個(gè)定義很寬泛,小到一個(gè)按鈕的點(diǎn)擊狀態(tài)、輸入框的文本,大到數(shù)據(jù)庫(kù)里的博文和評(píng)論、網(wǎng)絡(luò)連接狀態(tài),都屬于“狀態(tài)”。
Android 應(yīng)用本質(zhì)上就是在“展示狀態(tài)”:比如沒(méi)網(wǎng)時(shí)顯示的提示、點(diǎn)擊按鈕時(shí)的漣漪效果、圖片上用戶添加的貼紙,本質(zhì)都是在呈現(xiàn)不同時(shí)刻的“狀態(tài)”。

二、狀態(tài)和“組合/重組”的關(guān)系

Compose 是“聲明式”工具集,和傳統(tǒng) XML 布局的“命令式”完全不同——它更新界面的唯一方式,是用新參數(shù)重新調(diào)用可組合項(xiàng)(也就是那些帶 @Composable 注解的函數(shù))。這些參數(shù),其實(shí)就是界面狀態(tài)的“表現(xiàn)形式”。

這里要先搞懂三個(gè)關(guān)鍵術(shù)語(yǔ):

  • 組合:Compose 執(zhí)行可組合項(xiàng)后,生成的“界面描述”(相當(dāng)于把代碼翻譯成了手機(jī)能顯示的界面結(jié)構(gòu));
  • 初始組合:第一次運(yùn)行可組合項(xiàng),創(chuàng)建出初始界面的過(guò)程;
  • 重組:當(dāng)狀態(tài)變化時(shí),重新運(yùn)行可組合項(xiàng)、更新“組合”(也就是更新界面)的過(guò)程。

舉個(gè)直觀例子, HelloContent 函數(shù):

@Composable private fun HelloContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Hello!", ...)
        OutlinedTextField(
            value = "", // 固定空字符串,沒(méi)有關(guān)聯(lián)狀態(tài)
            onValueChange = { }, // 沒(méi)處理輸入變化
            label = { Text("Name") }
        )
    }
}

運(yùn)行后輸入文本沒(méi)反應(yīng)——因?yàn)?TextField 不會(huì)“自動(dòng)更新”:它的 value 參數(shù)是固定空字符串,狀態(tài)沒(méi)變化,就不會(huì)觸發(fā)“重組”,界面自然不變。
這就是 Compose 的核心規(guī)則:只有狀態(tài)變了,且可組合項(xiàng)用到了這個(gè)狀態(tài),才會(huì)觸發(fā)重組更新界面

三、可組合項(xiàng)里怎么存狀態(tài)?(2個(gè)核心API)

要讓界面能跟著狀態(tài)變,得解決兩個(gè)問(wèn)題:① 把狀態(tài)存起來(lái);② 讓狀態(tài)變化能觸發(fā)重組。Compose 提供了兩個(gè)關(guān)鍵 API 配合解決:

1. remember:負(fù)責(zé)“存儲(chǔ)狀態(tài)”

remember 是個(gè)“記憶工具”,作用是把對(duì)象存儲(chǔ)在“組合”里

  • 初始組合時(shí),計(jì)算一個(gè)值并存起來(lái);
  • 重組時(shí),直接返回之前存儲(chǔ)的值(不會(huì)重新計(jì)算);
  • 注意:如果調(diào)用 remember 的可組合項(xiàng)被從界面中移除(比如切換頁(yè)面時(shí)),remember 會(huì)“忘記”存儲(chǔ)的值(相當(dāng)于臨時(shí)緩存,隨界面生命周期變化)。

它既能存不可變對(duì)象(比如固定的字符串),也能存可變對(duì)象——但要配合下面的 API 才能觸發(fā)重組。

2. mutableStateOf:負(fù)責(zé)“讓狀態(tài)可觀察”

mutableStateOf 會(huì)創(chuàng)建一個(gè) MutableState<T> 類型的對(duì)象,這是 Compose 內(nèi)置的“可觀察類型”,核心特點(diǎn)是:

  • 它是個(gè)接口,核心是 var value: T(可以修改值);
  • 只要修改 value 的值,所有“讀取過(guò)這個(gè) value”的可組合項(xiàng),都會(huì)被自動(dòng)安排“重組”(也就是更新界面)。

簡(jiǎn)單說(shuō):remember 負(fù)責(zé)“存住狀態(tài)”,mutableStateOf 負(fù)責(zé)“讓狀態(tài)變化能被 Compose 感知”,兩者搭配才能實(shí)現(xiàn)“狀態(tài)變 → 界面變”。

四、聲明 MutableState 的3種方式(語(yǔ)法糖,按需選)

mutableStateOf 通常和 remember 一起用,有3種等效寫法,只是語(yǔ)法不同,目的是讓代碼更易讀:

特性val nameState = remember { mutableStateOf(“”) }var name by remember { mutableStateOf(“”) }val (name, setName) = remember { mutableStateOf(“”) }
變量類型val (不可變引用)var (可變屬性)val (兩個(gè)不可變引用)
訪問(wèn)值nameState.valuenamename
修改值nameState.value = "New"name = "New"setName("New")
本質(zhì)直接持有 State 對(duì)象使用屬性委托,編譯器自動(dòng)處理 .value使用解構(gòu)聲明
代碼風(fēng)格顯式,能清楚看到狀態(tài)對(duì)象簡(jiǎn)潔,類似普通的可變變量類似于 React Hooks 的風(fēng)格
需要導(dǎo)入無(wú)特殊導(dǎo)入import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
無(wú)特殊導(dǎo)入
適用場(chǎng)景需要將 State 對(duì)象本身傳遞給其他函數(shù)時(shí)最常用、最推薦的寫法,代碼簡(jiǎn)潔直觀習(xí)慣函數(shù)式風(fēng)格,希望將值和設(shè)置器分開(kāi)

在實(shí)際開(kāi)發(fā)中,第二種方式 (by 委托) 因其極高的可讀性和簡(jiǎn)潔性而成為社區(qū)和官方最推崇的標(biāo)準(zhǔn)寫法(傳遞的是值)。第一種方式在需要傳遞狀態(tài)引用時(shí)很有用。第三種方式則提供了一種不同的代碼風(fēng)格,適合那些喜歡顯式分離“值”和“更新函數(shù)”的開(kāi)發(fā)者。

五、傳遞對(duì)象和傳遞值的區(qū)別

傳遞狀態(tài)對(duì)象和傳遞值在 Compose 中有本質(zhì)的區(qū)別,這關(guān)系到重組機(jī)制數(shù)據(jù)流方向

1. 核心區(qū)別

特性傳遞值傳遞狀態(tài)對(duì)象
傳遞的內(nèi)容當(dāng)前的數(shù)據(jù)值包含數(shù)據(jù)和更新能力的對(duì)象
接收方能否修改? 不能? 能
重組范圍傳遞方重組 → 接收方重組接收方可獨(dú)立重組
數(shù)據(jù)流單向數(shù)據(jù)流雙向數(shù)據(jù)流

2. 具體例子說(shuō)明

例子1:傳遞值(單向數(shù)據(jù)流)
@Composable
fun ParentComponent() {
    var name by remember { mutableStateOf("") }
    Column {
        // 傳遞值給子組件
        ChildComponentReadOnly(value = name)
        // 父組件自己處理修改
        TextField(
            value = name,
            onValueChange = { name = it }
        )
    }
}
@Composable
fun ChildComponentReadOnly(value: String) {
    // 子組件只能讀取值,不能修改
    Text("Hello, $value!")
    // 如果嘗試修改會(huì)編譯錯(cuò)誤:
    // value = "New" // ? 編譯錯(cuò)誤!
}

特點(diǎn)

  • 數(shù)據(jù)流是單向的:父組件 → 子組件
  • 子組件是純展示的,沒(méi)有副作用
  • 狀態(tài)管理完全由父組件控制
例子2:傳遞狀態(tài)對(duì)象(雙向數(shù)據(jù)流)
@Composable
fun ParentComponent() {
    val nameState = remember { mutableStateOf("") }
    Column {
        // 傳遞狀態(tài)對(duì)象給子組件
        ChildComponentWithState(state = nameState)
        // 父組件也能看到子組件的修改
        Text("Parent sees: ${nameState.value}")
    }
}
@Composable
fun ChildComponentWithState(state: MutableState<String>) {
    TextField(
        value = state.value,
        onValueChange = { state.value = it }
    )
    // 子組件可以直接修改狀態(tài)
    Button(onClick = { state.value = "Reset" }) {
        Text("Reset")
    }
}

特點(diǎn)

  • 數(shù)據(jù)流是雙向的:父組件 ↔ 子組件
  • 子組件可以直接修改狀態(tài)
  • 雙方都能實(shí)時(shí)看到對(duì)方的修改

3. 重組行為的區(qū)別

傳遞值的情況:
@Composable
fun Parent() {
    var count by remember { mutableStateOf(0) }
    // 當(dāng)count變化時(shí),Parent會(huì)重組
    // Child也會(huì)重組,因?yàn)樗邮樟诵碌闹?
    Child(value = count)
    Button(onClick = { count++ }) {
        Text("Increment")
    }
}
@Composable
fun Child(value: Int) {
    Text("Count: $value") // 接收新值,會(huì)重組
}
傳遞狀態(tài)對(duì)象的情況:
@Composable
fun Parent() {
    val countState = remember { mutableStateOf(0) }
    // Parent不會(huì)重組,因?yàn)閏ountState引用沒(méi)變
    // Child自己處理重組
    Child(state = countState)
    Button(onClick = { countState.value++ }) {
        Text("Increment")
    }
}
@Composable
fun Child(state: MutableState<Int>) {
    Text("Count: ${state.value}") // 自己讀取狀態(tài),自己重組
}

4. 小結(jié)

方面傳遞值傳遞狀態(tài)對(duì)象
控制權(quán)集中控制分散控制
數(shù)據(jù)流單向雙向
組件職責(zé)展示職責(zé)業(yè)務(wù)邏輯職責(zé)
測(cè)試難度容易測(cè)試較難測(cè)試
推薦程度? 優(yōu)先使用?? 特定場(chǎng)景使用

最佳實(shí)踐:優(yōu)先使用傳遞值的方式,遵循單向數(shù)據(jù)流原則。只有在子組件確實(shí)需要直接修改狀態(tài),且這種修改是合理的業(yè)務(wù)需求時(shí),才考慮傳遞狀態(tài)對(duì)象。

六、實(shí)際用法:讓狀態(tài)控制界面

狀態(tài)的核心作用,是“決定界面該顯示什么”。比如優(yōu)化版的 HelloContent

@Composable fun HelloContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        // 用 by 委托語(yǔ)法,聲明并存儲(chǔ)“姓名狀態(tài)”,初始值為空
        var name by remember { mutableStateOf("") }
        // 狀態(tài)控制界面:只有姓名不為空時(shí),才顯示問(wèn)候語(yǔ)
        if (name.isNotEmpty()) {
            Text(text = "Hello, $name!") // 用到了 name 狀態(tài)
        }
        OutlinedTextField(
            value = name, // 綁定狀態(tài):輸入框的文本 = 姓名狀態(tài)
            onValueChange = { name = it }, // 輸入變化時(shí),更新?tīng)顟B(tài)
            label = { Text("Name") }
        )
    }
}

這里的邏輯鏈很清晰:

  1. 輸入框輸入文本 → onValueChange 回調(diào)更新 name 狀態(tài);
  2. name 狀態(tài)變化 → 觸發(fā)用到 name 的可組合項(xiàng)(if 里的 TextTextField 本身)重組;
  3. 重組時(shí),if (name.isNotEmpty()) 條件生效,顯示問(wèn)候語(yǔ);輸入框也同步顯示新的 name 值。

這就是 Compose 處理狀態(tài)的核心流程:狀態(tài)存儲(chǔ)(remember)→ 狀態(tài)觀察(mutableStateOf)→ 狀態(tài)變化觸發(fā)重組 → 界面更新

到此這篇關(guān)于Android Compose 狀態(tài)的概念的文章就介紹到這了,更多相關(guān)Android Compose 狀態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android實(shí)現(xiàn)Tab布局的4種方式(Fragment+TabPageIndicator+ViewPager)

    Android實(shí)現(xiàn)Tab布局的4種方式(Fragment+TabPageIndicator+ViewPager)

    Android現(xiàn)在實(shí)現(xiàn)Tab類型的界面方式越來(lái)越多,本文詳細(xì)介紹了Android實(shí)現(xiàn)Tab布局的4種方式,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-11-11
  • Android Web3j OOM解決詳解

    Android Web3j OOM解決詳解

    這篇文章主要介紹了Android Web3j OOM解決詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • GridView實(shí)現(xiàn)桌面圖標(biāo)顯示案例

    GridView實(shí)現(xiàn)桌面圖標(biāo)顯示案例

    這篇文章主要為大家詳細(xì)介紹了GridView實(shí)現(xiàn)桌面圖標(biāo)顯示案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Android編寫簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng)

    Android編寫簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng)

    網(wǎng)絡(luò)爬蟲(chóng)是捜索引擎抓取系統(tǒng)的重要組成部分。爬蟲(chóng)的主要目的是將互聯(lián)網(wǎng)上的網(wǎng)頁(yè)下載到本地形成一個(gè)或聯(lián)網(wǎng)內(nèi)容的鏡像備份。本文的主要內(nèi)容是講在Android中如何編寫簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng)。
    2016-07-07
  • Android如何實(shí)現(xiàn)時(shí)間線效果

    Android如何實(shí)現(xiàn)時(shí)間線效果

    這篇文章主要介紹了?Android如何實(shí)現(xiàn)時(shí)間線效果,下面文章圍繞?Android如何實(shí)現(xiàn)時(shí)間線效果的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,具有一定的參考價(jià)值?,需要的朋友可以參考一下
    2021-11-11
  • android繪制觸點(diǎn)軌跡的代碼

    android繪制觸點(diǎn)軌跡的代碼

    這篇文章主要為大家詳細(xì)介紹了android繪制觸點(diǎn)軌跡的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Android仿美團(tuán)拖拽效果實(shí)例代碼

    Android仿美團(tuán)拖拽效果實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于Android仿美團(tuán)拖拽效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格示例

    Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格示例

    這篇文章主要介紹了Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格,結(jié)合具體實(shí)例形式分析了Android實(shí)現(xiàn)九宮格的具體步驟與相關(guān)布局、功能實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • Ubuntu Android源碼以及內(nèi)核下載與編譯

    Ubuntu Android源碼以及內(nèi)核下載與編譯

    本文主要介紹Android源碼的下載和編譯,這里整理了相關(guān)資料及如何下載和編譯的詳細(xì)步驟,有需要的小伙伴可以參考下
    2016-09-09
  • MVPXlistView展示上拉下拉效果

    MVPXlistView展示上拉下拉效果

    這篇文章主要為大家詳細(xì)介紹了MVPXlistView展示上拉下拉效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評(píng)論

井冈山市| 东兰县| 永清县| 乐都县| 友谊县| 馆陶县| 井冈山市| 呼玛县| 通化县| 昌图县| 洪洞县| 黑山县| 精河县| 和田市| 北海市| 逊克县| 合阳县| 利川市| 平湖市| 陇南市| 遵义县| 永泰县| 堆龙德庆县| 南安市| 平罗县| 桓台县| 扎兰屯市| 宜兰市| 蚌埠市| 宽城| 凤山县| 固安县| 松溪县| 乐昌市| 万山特区| 卢湾区| 驻马店市| 体育| 依兰县| 安阳县| 呼图壁县|