Android Compose 入門,深入底層源碼分析

来源:https://www.cnblogs.com/laomuji666/p/18126525
-Advertisement-
Play Games

Android Compose 入門,深入底層源碼分析 我是跟著AS官網學習的,但是官方的教程寫的不是很詳細.官網鏈接 首先創建一個Compose項目,目錄結構是這樣: ui -> theme -> -> Color.kt -> -> Theme.kt -> -> Type.kt MainActiv ...


Android Compose 入門,深入底層源碼分析

我是跟著AS官網學習的,但是官方的教程寫的不是很詳細.官網鏈接
首先創建一個Compose項目,目錄結構是這樣:
ui
-> theme
-> -> Color.kt
-> -> Theme.kt
-> -> Type.kt
MainActivity.kt
通過閱讀源碼,發現實際上還少了一個Shapes.kt,我手動添加了.

Type.kt

/**  
 * 存放組件的Style  
 * Typography全部是文字的屬性
 * 點開Typography的代碼,結構很簡單.
 * 存了一些TextStyle,提供以下功能:
 * 主構造函數: 使用一些預設參數初始化各個TextStyle
 * copy: 複製一份
 * equals: 比較每一個TextStyle
 * hashCode: 計算hash,把每個TextStyle都計算進去.
 * fromToken: internal修飾,為Typography類增加拓展函數,根據傳進來的enum,確認獲取哪個TextStyle.
 * 在class外部還有一個對象:
 * LocalTypography: internal修飾,被MaterialTheme作為預設參數使用
 */  
val Typography = Typography(  
    bodyLarge = TextStyle(  
        fontFamily = FontFamily.Default,  
        fontWeight = FontWeight.Normal,  
        fontSize = 16.sp,  
        lineHeight = 24.sp,  
        letterSpacing = 0.5.sp  
    )
)

Color.kt

/**  
 * 存放顏色值
 * darkColorScheme和lightColorScheme都屬於ColorScheme  
 * 點開ColorScheme的代碼,結構很簡單.
 * 存了一些Color,提供以下功能:
 * 主構造函數: 顏色委托給mutableStateOf,使顏色值的變化可以被Compose觀察.
 * copy: 複製一份
 * 剩下的是一些函數:
 * lightColorScheme: 提供預設的白天模式顏色
 * darkColorScheme: 提供預設的夜間模式顏色
 * ColorScheme.contentColorFor: 為ColorScheme類增加拓展函數,根據背景色使用對應的前景色,如果顏色不匹配,返回透明色.
 * contentColorFor: 提供一個函數,import這個函數來使用,如果顏色不匹配,返回黑色.
 * applyTonalElevation: internal修飾,為ColorScheme類增加拓展函數,返回新背景色,傳入的背景色加上高度.
 * surfaceColorAtElevation: 為ColorScheme類增加拓展函數,計算不同高度的surface錶面色調.
 * updateColorSchemeFrom: internal修飾,為ColorScheme類增加拓展函數,更新顏色,成本很高,但顏色委托給了mutableStateOf,忽略不變化的顏色值,提高運行效率.
 * fromToken: internal修飾,為ColorScheme類增加拓展函數,根據傳進來的enum,確認獲取哪個Color.
 * toColor: internal修飾,為ColorSchemeKeyTokens類增加拓展函數,將enum轉換為對應的顏色,調用fromToken.
 * 在class外部還有兩個對象:
 * LocalColorScheme: internal修飾,被MaterialTheme作為預設參數使用,預設使用lightColorScheme.
 * DisabledAlpha: internal修飾,禁用狀態的前景色.比如禁用按鈕的文字顏色.
 */  
val Purple80 = Color(0xFFD0BCFF)  
val PurpleGrey80 = Color(0xFFCCC2DC)  
val Pink80 = Color(0xFFEFB8C8)  

val Purple40 = Color(0xFF6650a4)  
val PurpleGrey40 = Color(0xFF625b71)  
val Pink40 = Color(0xFF7D5260)  

//深色模式  
val DarkColorScheme = darkColorScheme(  
    primary = Purple80,  
    secondary = PurpleGrey80,  
    tertiary = Pink80  
)  
  
//淺色模式  
val LightColorScheme = lightColorScheme(  
    primary = Purple40,  
    secondary = PurpleGrey40,  
    tertiary = Pink40,  
)

Shapes.kt

/**  
 * 預設創建的項目里沒有創建Shapes  
 * 這裡也簡單介紹一下  
 * 點開Shapes代碼,結構很簡單.  
 * 存放了一些形狀,提供以下功能:  
 * 主構造函數: 存放一些CornerBasedShape  
 * CornerBasedShape基於角的形狀,子類有: AbsoluteCutCornerShape,AbsoluteRoundedCornerShape,CutCornerShape,RoundedCornerShape.  
 * https://developer.android.com/reference/kotlin/androidx/compose/foundation/shape/CornerBasedShape * copy: 複製一份  
 * equals: 比較每個shape  
 * hashCode: 計算hash,把每個shape都計算進去.  
 * 類外部:  
 * ShapeDefaults: 提供CornerBasedShape的預設參數  
 * top,bottom,start,end: internal修飾,幫助組件獲取Shape.  
 * fromToken: internal修飾,根據傳入的enum,返回對應的Shape.  
 * toShape: internal修飾,為ShapeKeyTokens增加擴展函數,把enum轉為Shape,調用fromToken.  
 * LocalShapes: internal修飾,被MaterialTheme作為預設參數使用,預設使用ShapeDefaults.  
 */val shapes = Shapes(  
    extraSmall = ShapeDefaults.ExtraSmall  
)

Theme.kt

/**  
 * 構建一個Theme用來使用  
 * 如果不用自己構建的theme,會使用預設的theme.  
 * Theme很簡單,分為兩部分.  
 * 由Compose托管的:  
 * 使用colorScheme,shapes,typography,content創建一個MaterialTheme.  
 * content使用這個MaterialTheme,並且這個MaterialTheme會遞歸傳遞給content內的@Composable修飾的函數.  
 * 非Compose托管的:  
 * 一些不屬於View的,屬於window的.如狀態欄顏色,導航欄是否顯示等.  
 * 然後是MaterialTheme的源碼
 * MaterialTheme是一個@Composable修飾的函數,按照順序拆解:
 * rememberedColorScheme,用來更新顏色.調用updateColorSchemeFrom.使用remember讓currentComposer緩存colorScheme.copy()返回的對象,下次重組時繼續使用該值,涉及的內容太多,這裡不再深入.
 * rippleIndication,波紋動畫,預設使用透明色,也就是沒有波紋動畫.
 * selectionColors,文字選中顏色,預設使用:rememberedColorScheme.primary
 * CompositionLocalProvider,一個@Composable修飾的函數,使用上面的參數構建一個ProvidedValue對象,調用currentComposer.startProviders保存這些對象,然後調用content繪製,繪製時會使用這些ProvidedValue對象,然後調用currentComposer.endProviders()終止記錄.
 */  
/**  
 * @param darkTheme 是否是深色模式  
 * @param dynamicColor 動態顏色 安卓12(api31) 新增,會基於系統壁紙的顏色使用對應的顏色,https://developer.android.com/develop/ui/views/theming/dynamic-colors  
 * @param content Composable代碼塊,使用colorScheme作為主題色  
 */  
@Composable  
fun Study1Theme(  
    darkTheme: Boolean = isSystemInDarkTheme(),  
    dynamicColor: Boolean = true,  
    content: @Composable () -> Unit  
) {  
    //Material Design 需要的顏色  
    val colorScheme = when {  
        //使用動態顏色,跟隨壁紙,只有大於api31才能使用  
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {  
            val context = LocalContext.current  
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)  
        }  
  
        darkTheme -> DarkColorScheme  
        else -> LightColorScheme  
    }  
  
    //獲取View,@Composable的組合函數實際上是一個View  
    val view = LocalView.current  
    //不是編輯模式的情況下,設置一些參數  
    if (!view.isInEditMode) {  
        //window不是Compose管理的對象,需要用SideEffect來共用Compose狀態,SideEffect保證每次重組後都會執行  
        SideEffect {  
            //設置status bar 顏色  
            val window = (view.context as Activity).window  
            window.statusBarColor = colorScheme.primary.toArgb()  
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme  
        }  
    }  
  
    //顏色,字體,代碼塊構建一個MaterialTheme對象,代碼塊的MaterialTheme對象會使用這個構建的對象  
    MaterialTheme(  
        colorScheme = colorScheme,  
        typography = typography,  
        shapes = shapes,  
        content = content  
    )  
}

MainActivity.kt

這個沒什麼好說的,官方的教程說的很明白了.這裡簡單貼一下代碼.

class MainActivity : ComponentActivity() {  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        //setContent是Kotlin的擴展函數,使用Compose創建視窗  
        setContent {  
            //Study1Theme在theme/Theme.kt里,生成MaterialTheme給整個代碼塊用  
            Study1Theme(dynamicColor = false) {  
                //使用一個@Composable函數來作為界面的入口  
                MyApp(Modifier.fillMaxSize())  
            }  
        }    }  
  
    //界面入口,用來複用函數  
    @Composable  
    fun MyApp(modifier: Modifier = Modifier){  
        //Surface,一般顯示組件的顏色,如卡片,表格,菜單的背景色  
        Surface(  
            //Modifier.fillMaxSize() 鋪滿父組件  
            modifier = modifier,  
            //使用Study1Theme里創建的MaterialTheme的colorScheme  
            //colorScheme現在有深色淺色兩種模式,也可以添加更多風格.  
            color = MaterialTheme.colorScheme.primary  
        ) {  
            //Surface函數的最後一個參數是content: @Composable () -> Unit  
            //@Composable註解修飾的函數只能被同樣@Composable修飾的函數調用  
            SayHello("Android")  
        }  
    }  
  
    //顯示一個文本  
    @Composable  
    fun SayHello(name: String, modifier: Modifier = Modifier) {  
        Surface(color = MaterialTheme.colorScheme.primary) {  
            Text(  
                text = "Hello $name!",  
                modifier = modifier.padding(24.dp)  
            )  
        }  
    }  
  
    //Preview可以預覽無參或者有預設參數的Compose函數  
    @Preview(showBackground = true, name = "Say Hello Preview")  
    @Composable  
    fun SayHelloPreview(name: String = "Compose") {  
        Study1Theme(dynamicColor = false) {  
            MyApp()  
        }  
    }  
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 在我們上一篇文章瞭解了單元測試的基本概念和用法之後,今天我們來聊一下 TDD(測試驅動開發) 測試驅動開發 (TDD) 測試驅動開發英文全稱是Test Driven Development 簡稱 TDD。 根據 UncleBob 的 TDD 描述總結 我們先創建一個測試項目 直接在 VS 創建 ...
  • Keycloak是一個功能強大的開源身份和訪問管理系統,提供了一整套解決方案,包括用戶認證、單點登錄(SSO)、身份聯合、用戶註冊、用戶管理、角色映射、多因素認證和訪問控制等。它廣泛應用於企業和雲服務,可以簡化和統一不同應用程式和服務的安全管理,支持自托管或雲部署,適用於需要安全、靈活且易於擴展的用 ...
  • Avalonia是一個強大的跨平臺UI框架,允許開發者構建豐富的桌面應用程式。 它提供了眾多UI組件、靈活的佈局系統、可定製的樣式以及事件處理機制。 在這篇博客中,我們將詳細解析Avalonia的UI組件、UI組件的生命周期、佈局、樣式和事件處理。 一、UI組件 Avalonia提供了豐富的UI組件 ...
  • 在我寫虛擬記憶體時遇到一些問題,jalr t0就是可以的,而call main則沒辦法成功 而且這裡預設main是偏移前的地址,怪哉!!! 讓我們看看jalr 和call(偽指令!!!) 然後在鏈接後看看main的地址,主要看程式中main是不是偏移 懸著的心也死了!!! 查看一下ucore也有類似的 ...
  • linux伺服器部署了一個tcp服務,需要進行併發壓力測試 看看伺服器能支持多少個tcp長連接 預計會有50w個連接 需要設置linux 不然是無法支持這麼多連接的 如果達到這個值是無法建立新連接的 報錯信息一般為 too many open files 1 , fs.file-max linux系 ...
  • setreuid(-1,foo) 為何有時更新 saved set-user-id 有時不更新?man setreuid 中關於 SUID 變更的說明是否正確?如此設計有何考慮?本文通過閱讀 linux 源碼為你揭秘 ...
  • 痞子衡嵌入式半月刊: 第 97 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
  • @目錄前言簡介一、準備工作1.1 創建寫入腳本1.2 設置執行許可權1.3 添加定時任務1.4 配置生效二、Tomcat日誌 按每天分割2.1 創建一個 sh文件2.2 設置執行許可權2.3 設置crontab指令,指定每日定時任務2.4 配置生效總結 前言 請各大網友尊重本人原創知識分享,謹記本人博客 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...