您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Android開發(fā)Compose remember原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Android開發(fā)Compose remember原理是什么”吧!
假設(shè)有這么一個“隨機底色文本”的需求:實現(xiàn)一個 Text,其背景色每次啟動都隨機產(chǎn)生,且生命周期內(nèi)不變
用Compose可以實現(xiàn)如下:
private val items = arrayOf(Color.Red, Color.Gray, Color.Magenta, Color.Blue, Color.Green, Color.Cyan) @Composable fun ColorText(name: String) { val color = items.random() val clicked = mutableStateOf(0) Log.d("ct", "ui compose") Column { Text( text = "I'm colored: ${clicked.value}", modifier = Modifier .padding(16.dp) .background(color) .clickable { Log.d("ct", "clicked") clicked.value = clicked.value + 1 } ) } }
Text
調(diào)用 Modifier.background
,設(shè)置隨機從items中取的顏色,每次新的啟動,都可能不一樣
然而很遺憾,上面的背景色雖然是隨機產(chǎn)生,但是單次生命周期里,就可能發(fā)生變化
更奇怪的是,改變的 clicked 值,并沒有如預(yù)期一樣生效,一直是0
現(xiàn)象和代碼不一?
首先,上述代碼中的“點擊計數(shù)” clicked,僅僅是為了測試而存在。因為它是一個 MutableState
對象,點擊后改變其值,會觸發(fā)Recomposition流程,于是組件刷新。這樣一來,color 的值將重新由隨機函數(shù)算出,我們就看到背景色在變化了
同理,雖然我們好像在點擊的時候改變了 clicked 的值,希望像view系統(tǒng)一樣,界面直接響應(yīng)響應(yīng)。但是,因為Recomposition的存在,它又被重新構(gòu)造了,所以其值還是0
要實現(xiàn)背景色的整個生命周期固定,但點擊文本后,點擊計數(shù)要更新,應(yīng)該這么做:
@Composable fun ColorText(name: String) { val color = remember { items.random() } val clicked = remember { mutableStateOf(0) } //... }
僅僅將color和clicked由 remember
包裹起來就解決了問題
前面功能的實現(xiàn),全仗著remember
的加持。它究竟是個啥?
我們先從顏色的remember著手,它調(diào)用的是這個:
@Composable inline fun <T> remember(calculation: @DisallowComposableCalls () -> T): T = currentComposer.cache(false, calculation)
其注釋寫明了兩個關(guān)鍵點,這也是它的功能描述:
記憶由calculation
返回的值,僅在composition中執(zhí)行
在Recomposition過程中,不會重新計算,而是直接返回第1步的值
那么這又是怎么做到的呢?
進一步的相關(guān)代碼:
@ComposeCompilerApi inline fun <T> Composer.cache(invalid: Boolean, block: () -> T): T { @Suppress("UNCHECKED_CAST") return rememberedValue().let { // 無效或Empty值時,走if流程,計算并保存值,否則直接返回 // remember傳入的invalid為false,所以肯定走值判斷 if (invalid || it === Composer.Empty) { val value = block() updateRememberedValue(value) value } else it } as T } // 要么返回Composer.Empty ,要么返回傳給updateRememberedValue的值 @ComposeCompilerApi fun rememberedValue(): Any? // 更新調(diào)用rememberedValue()后的值,且此值在下一次調(diào)用rememberedValue()時返回 @ComposeCompilerApi fun updateRememberedValue(value: Any?) interface Composer { // .... companion object { /** * 用于標(biāo)記無值的狀態(tài) */ val Empty = object { override fun toString() = "Empty" } } }
從上述代碼注釋中,基本上已經(jīng)對原理很清楚了,簡單地說就是:
由composer作為存儲控制
無值時,走初始化邏輯并返回值,同時存儲該值;有值時,直接返回已存儲的值
顏色的“值不變”清楚了,那點擊計數(shù)的“值變”又是怎么回事呢?
其實如出一轍,只是點擊計數(shù)remember的,不是普通值,而是一個 MutableState
類型。這樣一來,它就有兩層含義了:
MutableState對象本身在整個composition生命周期不變 —— 即類似普通值的狀態(tài)一致性
MutableState對象所存儲的實際值,可變 —— 這用以觸發(fā)Recomposition,并且獲取更新值
到此,相信大家對“Android開發(fā)Compose remember原理是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。