Compose筆記(三十八)--CompositionLocal

? ? ? ? 這一節主要了解一下CompositionLocal,CompositionLocal是Jetpack Compose中用于組件樹內隱式數據傳遞的核心機制,其設計初衷是解決跨多層組件的數據共享問題,避免通過函數參數逐層傳遞數據。簡單總結:

API:
(1)compositionLocalOf<T>
創建一個動態的CompositionLocal實例,當值變化時,僅觸發讀取該值的組件重組。
(2)staticCompositionLocalOf<T>
創建一個靜態的CompositionLocal實例,值變化時觸發整個作用域內所有組件重組。?
(3)CompositionLocalProvider
為子組件樹提供CompositionLocal的值,作用域僅限于其內容塊。?
場景:
1. 主題與樣式配置,最常見的場景是傳遞應用主題信息(顏色、字體、間距等),讓組件樹中的所有子組件都能訪問統一的樣式配置。
2. 上下文信息傳遞,替代傳統Android中的Context傳遞,在Compose組件樹中共享上下文相關數據。?
3. 用戶狀態與全局配置,共享用戶信息(如登錄狀態、權限)或全局配置,讓深層嵌套的組件也能訪問這些狀態。
4. 工具類與服務共享,傳遞工具類實例或服務,避免在每個組件中單獨初始化。

栗子:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.spprivate val LocalAppTheme = compositionLocalOf<AppTheme> {error("No AppTheme provided")
}data class AppTheme(val primaryColor: Color,val textColor: Color,val fontSize: Float
)@Composable
fun ThemeProvider(theme: AppTheme = AppTheme(primaryColor = Color.Blue,textColor = Color.White,fontSize = 16f),content: @Composable () -> Unit
) {CompositionLocalProvider(LocalAppTheme provides theme) {content()}
}@Composable
fun ThemedText(text: String) {val theme = LocalAppTheme.currentText(text = text,color = theme.textColor,fontSize =18.sp)
}@Composable
fun CompositionLocalExample() {ThemeProvider {Box(modifier = Modifier.fillMaxSize().background(LocalAppTheme.current.primaryColor),contentAlignment = Alignment.Center) {ThemedText("Hello CompositionLocal!")}}
}
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifierdata class PermissionState(val cameraGranted: Boolean,val locationGranted: Boolean,val storageGranted: Boolean,val requestCamera: () -> Unit,val requestLocation: () -> Unit,val requestStorage: () -> Unit
)private val LocalPermissions = compositionLocalOf<PermissionState> {error("No PermissionState provided. Make sure to wrap your content with PermissionProvider.")
}@Composable
fun PermissionProvider(content: @Composable () -> Unit
) {var cameraGranted by remember { mutableStateOf(false) }var locationGranted by remember { mutableStateOf(false) }var storageGranted by remember { mutableStateOf(false) }val permissionState = PermissionState(cameraGranted = cameraGranted,locationGranted = locationGranted,storageGranted = storageGranted,requestCamera = { cameraGranted = true },  // 實際會調用真實的權限請求API,只是演示requestLocation = { locationGranted = true },requestStorage = { storageGranted = true })CompositionLocalProvider(LocalPermissions provides permissionState) {content()}
}@Composable
fun CameraFeature() {val permissions = LocalPermissions.currentColumn(horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Text("相機功能")if (permissions.cameraGranted) {Text("? 相機權限已授予")Button(onClick = { /* 使用相機的邏輯 */ }) {Text("拍照")}} else {Text("? 相機權限未授予")Button(onClick = permissions.requestCamera) {Text("請求相機權限")}}}
}@Composable
fun LocationFeature() {val permissions = LocalPermissions.currentColumn(horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Text("位置功能")if (permissions.locationGranted) {Text("? 位置權限已授予")Button(onClick = { /* 使用位置的邏輯 */ }) {Text("獲取當前位置")}} else {Text("? 位置權限未授予")Button(onClick = permissions.requestLocation) {Text("請求位置權限")}}}
}@Composable
fun FeaturesScreen() {Column(modifier = Modifier.fillMaxSize(),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.SpaceEvenly) {Text("應用功能", style = androidx.compose.material3.MaterialTheme.typography.headlineMedium)CameraFeature()LocationFeature()}
}@Composable
fun PermissionTest() {    PermissionProvider {FeaturesScreen()}
}

注意
避免濫用:CompositionLocal適合共享“全局/半全局”數據,若數據僅在少數幾層傳遞,直接用參數傳遞更清晰。
明確作用域:通過 CompositionLocalProvider限制數據的生效范圍,避免全局污染。
性能考量:CompositionLocal的值變化會導致依賴它的所有組件重組,不宜用于頻繁變化的數據。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90781.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90781.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90781.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決uniapp 使用uview生成小程序包太大無法上傳的問題

直接打包的插件內容優化后完美上傳&#xff0c; 相信眼尖的小伙伴已經發現了問題的關鍵 uview 會在每個組件里重復引css。導致包太大。 并且 它的格式是 data-v-哈希 沒法簡單的處理 需要壓縮通用規則。然后 再引用壓縮后的規則例如是然后 成功上傳

在線工具+網頁平臺來學習和操作Python與Excel相關技能

&#x1f517;一、在線平臺推薦&#xff08;免安裝&#xff09; ?Python平臺&#xff08;直接寫代碼、跑結果&#xff09;&#xff1a; 平臺 優點 地址 Google Colab 免費&#xff0c;支持圖表和文件操作&#xff0c;最推薦 https://colab.research.google.com …

R Excel 文件處理指南

R Excel 文件處理指南 引言 R語言作為一種強大的統計計算和圖形展示工具&#xff0c;在數據分析領域有著廣泛的應用。而Excel作為辦公軟件的佼佼者&#xff0c;在數據記錄和計算中也扮演著重要的角色。本文旨在介紹如何使用R語言處理Excel文件&#xff0c;包括讀取、寫入以及數…

億級流量短劇平臺架構演進:高并發場景下的微服務設計與性能調優

一、短劇系統概述與市場背景短劇作為一種新興的內容形式&#xff0c;近年來在移動互聯網領域迅速崛起。根據最新市場數據顯示&#xff0c;2023年中國短劇市場規模已突破300億元&#xff0c;用戶規模達到4.5億&#xff0c;平均每日觀看時長超過60分鐘。這種爆發式增長催生了對專…

4G手機控車模塊的核心功能與應用價值

4G手機控車模塊是基于4G無線通信技術實現車輛遠程監控、控制及數據交互的嵌入式設備。其核心功能包括通過4G網絡實現高速數據傳輸&#xff08;支持TCP/IP協議&#xff09;、遠程參數配置與設備管理、多網絡制式兼容&#xff0c;集成GPS/北斗定位功能&#xff0c;可實時獲取車輛…

【leetGPU】1. Vector Addition

問題 link: https://leetgpu.com/challenges/vector-addition Implement a program that performs element-wise addition of two vectors containing 32-bit floating point numbers on a GPU. The program should take two input vectors of equal length and produce a si…

瑞吉外賣學習筆記

TableField 作用: 當數據庫中表的列名與實體類中的屬性名不一致&#xff0c;使用TableField 使其對應 TableField("db_column_name") private String entityFieldName;exist 屬性 : 指定該字段是否參與增刪改查操作。 TableField(exist false) private String tempF…

RoPE:相對位置編碼的旋轉革命——原理、演進與大模型應用全景

“以復數旋轉解鎖位置關系的本質表達&#xff0c;讓Transformer突破長度藩籬” 旋轉位置編碼&#xff08;Rotary Position Embedding, RoPE&#xff09; 是由 Jianlin Su 等研究者 于2021年提出的突破性位置編碼方法&#xff0c;通過復數空間中的旋轉操作將相對位置信息融入Tra…

震網(Stuxnet):打開潘多拉魔盒的數字幽靈

在科技飛速發展的今天&#xff0c;代碼和數據似乎只存在于無形的數字世界。但如果我告訴大家&#xff0c;一段代碼曾悄無聲息地潛入一座受到嚴密物理隔離的核工廠&#xff0c;并成功摧毀了其中的物理設備&#xff0c;大家是否會感到一絲寒意&#xff1f;這不是科幻電影的情節&a…

一文讀懂:到底什么是 “具身智能” ?

今天咱們來好好聊聊一個最近很火的一個技術話題——具身智能&#xff01; 這個詞聽起來是不是有點難懂&#xff1f;其實我們可以簡單理解為&#xff1a;具身智能是具有身體的人工智能體。這樣是不是會容易理解一些&#xff1f; 具身智能&#xff08;Embodied Intelligence&…

企業級區塊鏈平臺Hyperchain核心原理剖析

Hyperchain作為國產自主可控的企業級聯盟區塊鏈平臺&#xff0c;其核心原理圍繞高性能共識、隱私保護、智能合約引擎及可擴展架構展開&#xff0c;通過多模塊協同實現企業級區塊鏈網絡的高效部署與安全運行。 以下從核心架構、關鍵技術、性能優化、安全機制、應用場景五個維度展…

論文閱讀-RaftStereo

文章目錄1 概述2 模塊說明2.1 特征抽取器2.2 相關金字塔2.3 多級更新算子2.4 Slow-Fast GRU2.5 監督3 效果1 概述 在雙目立體匹配中&#xff0c;基于迭代的模型是一種比較主流的方法&#xff0c;而其鼻祖就是本文要講的RaftStereo。 先來說下什么是雙目立體匹配。給定極線矯正…

內存優化:從堆分配到零拷貝的終極重構

引言 在現代高性能軟件開發中&#xff0c;內存管理往往是性能優化的關鍵戰場。頻繁的堆內存分配(new/delete)不僅會導致性能下降&#xff0c;還會引發內存碎片化問題&#xff0c;嚴重影響系統穩定性。本文將深入剖析高頻調用模塊中堆分配泛濫導致的性能塌方問題&#xff0c;并…

【GoLang#2】:基礎入門(工具鏈 | 基礎語法 | 內置函數)

前言&#xff1a;Go 的一些必備知識 1. Go 語言命名 Go的函數、變量、常量、自定義類型、包(package)的命名方式遵循以下規則&#xff1a; 首字符可以是任意的Unicode字符或者下劃線剩余字符可以是Unicode字符、下劃線、數字字符長度不限 Go 語言代碼風格及開發事項代碼每一行結…

Bert項目--新聞標題文本分類

目錄 技術細節 1、下載模型 2、config文件 3、BERT 文本分類數據預處理流程 4、對輸入文本進行分類 5、計算模型的分類性能指標 6、模型訓練 7、基于BERT的文本分類預測接口 問題總結 技術細節 1、下載模型 文件名稱--a0_download_model.py 使用 ModelScope 庫從模型倉…

sendfile系統調用及示例

好的&#xff0c;我們繼續學習 Linux 系統編程中的重要函數。這次我們介紹 sendfile 函數&#xff0c;它是一個高效的系統調用&#xff0c;用于在兩個文件描述符之間直接傳輸數據&#xff0c;通常用于將文件內容發送到網絡套接字&#xff0c;而無需將數據從內核空間復制到用戶空…

數據結構習題--刪除排序數組中的重復項

數據結構習題–刪除排序數組中的重復項 給你一個 非嚴格遞增排列 的數組 nums &#xff0c;請你 原地 刪除重復出現的元素&#xff0c;使每個元素 只出現一次 &#xff0c;返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 nums 中唯一元素的個數。 方法&…

Docker的容器設置隨Docker的啟動而啟動

原因也比較簡單&#xff0c;在docker run 的時候沒有設置–restartalways參數。 容器啟動時&#xff0c;需要增加參數 –restartalways no - 容器退出時&#xff0c;不重啟容器&#xff1b; on-failure - 只有在非0狀態退出時才從新啟動容器&#xff1b; always - 無論退出狀態…

JWT安全機制與最佳實踐詳解

JWT&#xff08;JSON Web Token&#xff09; 是一種開放標準&#xff08;RFC 7519&#xff09;&#xff0c;用于在各方之間安全地傳輸信息作為緊湊且自包含的 JSON 對象。它被廣泛用于身份驗證&#xff08;Authentication&#xff09;和授權&#xff08;Authorization&#xff…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘ipython’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘ipython’問題 摘要 在開發過程中&#xff0c;我們常常會遇到pip install報錯的問題&#xff0c;其中一個常見的報錯是 ModuleNotFoundError: No module named…