<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
看過Compose案例或者原始碼的你,相信肯定是見過 remember
了的。顧名思義,Compose是要讓我們的程式碼“記住”東西,那到底是記住什麼呢?要是不 remember
,相關功能就實現不了了嗎?
帶著這些問題,來一探究竟吧
假設有這麼一個“隨機底色文字”的需求:實現一個 Text,其背景色每次啟動都隨機產生,且生命週期內不變
用Compose可以實現如下:
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
呼叫 Modifier.background
,設定隨機從items中取的顏色,每次新的啟動,都可能不一樣
然而很遺憾,上面的背景色雖然是隨機產生,但是單次生命週期裡,就可能發生變化 —— 比如點選一下文字,如下圖:
更奇怪的是,改變的 clicked 值,並沒有如預期一樣生效,一直是0……
現象和程式碼不一?
首先,上述程式碼中的“點選計數” clicked,僅僅是為了測試而存在。因為它是一個 MutableState
物件,點選後改變其值,會觸發Recomposition流程,於是元件重新整理。這樣一來,color 的值將重新由隨機函數算出,我們就看到背景色在變化了
同理,雖然我們好像在點選的時候改變了 clicked 的值,希望像view系統一樣,介面直接響應響應。但是,因為Recomposition的存在,它又被重新構造了,所以其值還是0
要實現背景色的整個生命週期固定,但點選文字後,點選計數要更新,應該這麼做:
@Composable fun ColorText(name: String) { val color = remember { items.random() } val clicked = remember { mutableStateOf(0) } //... }
僅僅將color和clicked由 remember
包裹起來就解決了問題
前面功能的實現,全仗著remember
的加持。它究竟是個啥?
我們先從顏色的remember著手,它呼叫的是這個:
@Composable inline fun <T> remember(calculation: @DisallowComposableCalls () -> T): T = currentComposer.cache(false, calculation)
其註釋寫明瞭兩個關鍵點,這也是它的功能描述:
calculation
返回的值,僅在composition中執行那麼這又是怎麼做到的呢?
進一步的相關程式碼:
@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? // 更新呼叫rememberedValue()後的值,且此值在下一次呼叫rememberedValue()時返回 @ComposeCompilerApi fun updateRememberedValue(value: Any?) interface Composer { // .... companion object { /** * 用於標記無值的狀態 */ val Empty = object { override fun toString() = "Empty" } } }
從上述程式碼註釋中,基本上已經對原理很清楚了,簡單地說就是:
顏色的“值不變”清楚了,那點選計數的“值變”又是怎麼回事呢?
其實如出一轍,只是點選計數remember的,不是普通值,而是一個 MutableState
型別。這樣一來,它就有兩層含義了:
remember
的存在,其實就是 Compose 機制下的產物,用以解決recomposition時的值恢復問題。而因為它的“值不變”特性,還可以用來解決耗時計算的問題,即,耗時計算被remember了,那它就只會執行一次,避免了不必要的額外開銷
以上就是Android開發Compose remember原理解析的詳細內容,更多關於Android開發Compose remember的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45