D22/ 怎麽在 Compose 中用 Material Theme? - Theme

今天大概会聊到的范围

  • Theme

透过 Android Studio 内建的精灵建立一个新的 Compose 专案或是建立新的 "Empty Compose Activity" 时,会发现这样的 code :


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ProjectNameTheme {  // <--- 今天主角
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

可以发现预设的 Code 会在内容的 Composable 之外,再包一个 Theme。仔细研究一下这个 Theme。这个 Theme 通常是开启新的 Compose 专案时自动建立的。可以观察到这个 Theme 其实是对 MaterialTheme 的包装。

@Composable
fun ProjectNameTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),    
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }
    
    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

在 MaterialTheme 中,要提供 color 、typography、shapes。

设定的地方

    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

在 Android Studio 自动建立的 Theme 中,会判断是否是 dark mode,在不同的情况下使用不同的 "ColorPalette"

Color Palette 是 Material Design 中重要的概念。透过一组事先配好的颜色让整个 App 的颜色有一致性。要提供 MaterialTheme color,我们要提供的 Colors 物件时就需要提供这个 Palette 中所需要的各个颜色:

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    // 是否是 dark mode 
)

除了颜色之外,typography 可以定义 h1 ~ body 等不同字级。可以参考 Material Design 的 Type System 、另外还有 Shape System 可以设定在不同的情况下物件的形状。

使用的地方

Theme 已经配置好了,我们也将 content 包在 Theme 里面了,那要怎麽取得我们 Theme 的配置呢?

@Composable
fun UIComposable() {
    MaterialTheme() {
        Card(modifier = Modifier.background(MaterialTheme.colors.background)) {
            // ...
        }
    }
}

我们只需要透过 MaterialTheme.(colors | typography | shapes) 就可以取得对应的参数了!


在 Compose 中,使用 Theme 真的非常的简单,设定的地方和使用的地方都非常直觉。很好奇 Compose framework 实际上怎麽做到这件事的? 也许可以当成後续的主题吧!


Reference:


<<:  Day24

>>:  Day21 - Sort

中阶魔法 - 执行环境与执行堆叠

前情提要 上回偷拿远距离初阶魔法攻击艾草。 艾草:「我看你拿魔法丢我丢得挺顺的了(╬•᷅д•᷄╬),...

[day21]Vue实作-登出及会员功能实作

登出模式及未登入限制读取页面 navbar.vue调整 登出登入的切换调整 利用v-show来判断是...

Day27_是不是跟个资法卯上了~哈哈~CBPR-2021/10/10

想说CBPR是什麽? 与GDPR不同的是,CBPR并非是一套要求所有国家遵循的规范, 而更像是一种参...

Day15 竞合的团队气氛塑造 - Release line

团队成员的气氛,就应该是既竞争又是合作,而这个最高境界很大一部份要上面的PM推动。 因为人性是这样的...

如何撰写Dockerfile?

Docker指令整理 FROM: 使用到的 Docker Image 名称 MAINTAINER: ...