iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

開發 Android APP 的許多的開發方法,除了Compose UI 之外小弟知道的如下:

  1. 用 Java 程式語言開發
  2. 用 Kotlin 程式語言開發
  3. 用 Flutter 開發
  4. 用 Web View 內嵌網頁
  5. 用 React Native 開發
    如果有人向我一樣只熟悉其中1,2種開發方式,Compose UI 將是現在絕佳進入 Android APP 開發的選擇,除了 Kotlin 程式設計基礎之外,你和其他不管有沒有經驗的開發者,都是一樣的起跑點,透過努力學習即可掌握最新最棒的開發方法。

今日學習目標

要建構一個大房子,根基是很重要的,所以我們今天就來了解 Compose 主題的運作操作

Compose UI - Theme (主題)

官網上是這麼解釋什麼是 Theme(主題)的

Android 上的樣式和主題可讓您區分應用程式設計的詳細資料與 UI 結構和行為,與網頁設計中的樣式表類似。
「樣式」是屬性的集合,可指定單一 View 的外觀。樣式可指定各種屬性,例如字型顏色、字型大小、背景顏色等。
「主題」是套用至整個應用程式、活動或檢視區塊階層 (而不只是個別檢視畫面) 的屬性的集合。套用主題時,應用程式或活動中的每個檢視畫面都會套用該主題的每一個屬性 (須已支援)。主題也可以將樣式套用至非檢視元素,例如狀態列和視窗背景。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Exampleday3Theme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Greeting("Android")
                }
            }
        }
    }
}

activity

我們建立好一個 compose 的 project 之後,可以看到 Activity 的 onCreate() 裡面 setContent 中有一個預設的 Theme 叫做 Exampleday3Theme, 這個名稱是根據 Project 命名自動生成的,在 Android Studio 裏,滑鼠移動到 Exampleday3Theme 然後 cmd + B (我的系統是macOS) 可以見到 Exampleday3Theme 的原始碼:

@Composable
fun Exampleday3Theme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

這段程式碼是一個 Composable Function,主要是定義了兩個 Colors,分別是深色模式和淺色模式的主題,有兩個參數,第一個主要是指定是否為深色模式,第二個是我們的 content layout 內容,根據是否為深色模式來決定要使用的 Colors,之後 Apply 到 MaterialTheme 裡面。 MaterialTheme 也是一個 Composable Function, 有 colors、typography、shapes 與 Content.

我們從 darkColors Cmd+B 跳進去看一下是一個 Colors 的類別,裡面的變數都是 Observable 的 State。

@Stable
class Colors(
    primary: Color,
    primaryVariant: Color,
    secondary: Color,
    secondaryVariant: Color,
    background: Color,
    surface: Color,
    error: Color,
    onPrimary: Color,
    onSecondary: Color,
    onBackground: Color,
    onSurface: Color,
    onError: Color,
    isLight: Boolean
) {
    var primary by mutableStateOf(primary, structuralEqualityPolicy())
        internal set
    var primaryVariant by mutableStateOf(primaryVariant, structuralEqualityPolicy())
        internal set
    var secondary by mutableStateOf(secondary, structuralEqualityPolicy())
        internal set
...

而 Color 類別,是一個很單純放置顏色定義的類別,可以自己隨時客製顏色。

我們要使用設置好的顏色,只需要透過 MaterialTheme 來存取想要用的顏色屬性名稱就可以了,如下:

@Composable
fun Greeting(name: String) {
    Text(
        text = "Hello $name!",
        color = MaterialTheme.colors.primary
    )
}

而現在 primary 被 override 成 Theme.kt 裡面被定義為 Purple200 for dark mode 以及 Purple500 for light mode. 所以看到的 preview 畫面是:
preview1

如果我們想要把 Primary 的color 定義為橘色,很簡單只要改 theme/Color.kt 裡面新增一個新顏色:
“val Orange = Color(0xFFFF9800)”:

package com.hakka1.ithelp.example.day2.ui.theme

import androidx.compose.ui.graphics.Color

val Orange = Color(0xFFFF9800)
val Purple200 = Color(0xFFBB86FC)
val Purple500 = Color(0xFF6200EE)
val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5)

並且把 Theme.kt 的primary 變數值改為 Orange,然後重新把 Preview 畫面重新整理(refresh)後,TextView 的字體顏色就變成你想要的樣子。

private val DarkColorPalette = darkColors(
    primary = Orange,
    primaryVariant = Purple700,
    secondary = Teal200
)

private val LightColorPalette = lightColors(
    primary = Orange,
    primaryVariant = Purple700,
    secondary = Teal200

    /* Other default colors to override
    background = Color.White,
    surface = Color.White,
    onPrimary = Color.White,
    onSecondary = Color.Black,
    onBackground = Color.Black,
    onSurface = Color.Black,
    */
)

Preview2

雖然我們這一篇還沒有提到 UI 元件的控制,但我覺得 Theme 在專案開發會搭配 UI 設計師的想法而需要被客製化,今天先淺淺的瞭解一下 Theme 的觀念,未來有機會再來深入探討一番!

今天是中秋連假的第一天,祝大家月圓人團圓,佳節愉快。


上一篇
[Day2] 宣告式程式設計與指令式程式設計
下一篇
[Day4] Compose UI 寫中秋賀卡
系列文
30天 Android Jetpack Compose 奇幻旅程13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言