一、简介

通过此篇博客,你将学习:

  • Material Design入门攻略以及怎么针对您的运用对其进行自界说
  • Compose怎么完成Material Design体系
  • 怎么在运用中界说和运用色彩、排版和形状
  • 怎么设置组件的款式
  • 怎么支撑淡色主题和深色主题

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

二、Material主题设置

Jetpack Compose 供给了Material Design的完成,后者是一个用于创立数字化界面的归纳规划体系。Material Design组件(按钮 卡片、开关等)在Material主题设置的基础上构建而成,Material主题设置是一种体系化的方法,用于自界说Material Design以更好地反映您产品的品牌。一个Material主题由色彩、排版和形状特点组成。假如您自界说这些特点,相应设置会主动反映在您用来构建运用的组件中。

了解Material主题设置有助于您了解怎么为Jetpack Compose运用设置主题,因此咱们会在下面简要介绍相关概念。

2.1、色彩

Material Design界说了一些从语义上命名的色彩,供您在整个运用中运用:

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

primary是主要品牌色彩,secondary用于供给强调色。您可认为构成比照的区域供给色彩更深、更浅的变体。background和surface这两种色彩用于那些容纳这些概念上主流在运用“Surface”的组件的容器。此外,Material还界说了“on”色彩,即针对签字色彩上层的内容运用的色彩;例如,“surface”色容器中的文本选用了“on surface”色彩,Material组件已装备为运用这些主题色彩。例如,悬浮操作按钮的默许色彩为secondary,卡片的默许色彩为surface,诸如此类。

通过界说签字色彩,可以供给备用调色板,例如淡色主题和深色主题:

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

2.2、排版

同样,Materialh还界说了一些从语义上命名的字体款式:

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

虽然您可能不会按主题来更改字体款式,但运用字体份额可提升运用内部的一致性。假如您供给自己的字体和其他字体自界说设置,相应设置将反应在您的运用中运用的Material组件中,例如,引证蓝默许运用h6款式,按钮默许运用button

2.3、款式

Material支撑体系地运用形状来出现您的品牌并传达出品牌里面。它界说了3个类别:小型、中型和大型组件;每种组件都可以界说要运用的形状,然后自界说角的款式(切角和圆角)和巨细。

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

假如您自界说形状主题,相应设置将反应在很多组件中,例如,默许情况下,按钮和文本字段运用小型形状主题,卡片和对话框运用中型形状主题,动作条运用大型形状主题。

2.4、基准

Material默许选用“基准”主题,即紫色的配色计划、Roboto字体份额,以及以上图片所示的略成圆形的形状。

三、界说主题

3.1、MaterialTheme

在Jetpack Compose中完成主题设置的核心元素是MaterialTheme可组合项。假如将此可组合项放在Compose层次结构中,你就可认为其间的一切组件指定色彩、字体和形状的自界说设置。下面是此组合项在库中的界说方法:

@Composable
fun MaterialTheme(
    colors: Colors,
    typography: Typography,
    shapes: Shapes,
    content: @Composable () -> Unit
) {
    ...
}

以后,你可以运用MaterialTheme object检索传递到此可组合项的形参,以揭露colorstypographyshapes特点。后边,咱们将逐一进行深入介绍。

翻开Home.kt并找到Home可组合函数 – 这是运用的注进口点。请注意,虽然咱们声明晰MaterialTheme,但并未指定任何参数,因此会获得默许的”基准”款式:

@Composable
fun Home() {
    ...
    MaterialTheme {
        Scaffold( ... )
    }
}

咱们来创立色彩、字体和形状参数,为咱们的运用完成主题。

3.2、创立主题

如需会集设置款式,咱们建议您创立自己的可组合项,用于封装和装备MaterialTheme。这样依靠,您就可以在一个位置指定自己的主题自界说设置,并在多个位置(例如跨多个屏幕或@Preview)轻松地重复运用这些自界说设置。您可以根据需要创立多个主题可组合项。例如,假如您想针对运用的不同部分支撑不同的款式,就可以这样做。

新建一个名为Theme.kt的文件。增加一个名为JetnewsTheme的新可组合函数,此函数可接受其他可组合项作为内容并封装MaterialTheme

@Composable
fun JetnewsTheme(content: @Composable () -> Unit) {
    MaterialTheme(content = content)
}

现在,切换回Home.kt,并将MaterialTheme替换为JetnewsTheme(并将其导入)

- MaterialTheme {
+ JetnewsTheme {
...

在此屏幕上,@Preview不会立即显现任何变化。更新PostItemPreviewFeaturedPostPreview以运用新的JetnewsTheme可组合项来封装其内容,以便预览运用新的主题

@Preview("Featured Post")
@Composable
private fun FeaturePostPreview() {
    val post = remember { PostRepo.getFeaturePost() }
+ JetnewsTheme {
        FeaturedPost(post = post)
+ }
}

3.3、色彩

咱们要在运用中完成的调色板如下所示(目前只是一个淡色调色板;咱们很快会回来为设置深色主题供给支撑)

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

Compose中的色彩是运用COlor类界说的。借助多个构造函数,您可以将色彩指定为ULong,也可以按独自的色彩通道来指定色彩。

注意 :若要从用于指定色彩的常用“#dd0d3c”格局进行转换,请将“#”替换为“0xff”,即Color(0xffdd0d3c),其间“ff”表示完好的Alpha值。

theme软件包中创立一个新文件Color.kt。在此文件中将以色彩增加为尖端公共特点:

val Red700 = Color(0xffdd0D3c)
val Red800 = Color(0xffd00036)
val Red900 = Color(0xffc20029)

现在,咱们现已界说了运用的色彩。接下来,咱们将其合并到MaterialTheme所需的Colors目标中,然后将特定色彩分配到Material的签字色彩。切换回Theme.kt,然后增加以下代码:

private val LightColors = lightColors(
    primary = Red700,
    primaryVariant = Red900,
    onPrimary = Color.White,
    secondary = Red700,
    secondaryVariant = Red900,
    onSecondary = Color.White,
    error = Red800
)

下面,咱们要运用lightColors函数来构建Colors,这样即可供给合理的默许值,让咱们不必将构成Material调色板的一切色彩全都指定出来。例如,请注意,咱们尚未指定background色彩或许多”on”色彩,咱们将运用默许值。

现在,让咱们在运用中运用这些色彩。请更新JetnewsTheme可组合项以运用新的Colors

@Composable
fun JetnewsTheme(content: @Composable () -> Unit) {
    MaterialTheme(
+    colors = LightColors,
     content = content
    )
}

翻开Home.kt并刷新预览。请注意,新的配色计划会反应在TopAppBar等组件中。

3.4、排版

咱们要在运用中完成的字体份额如下所示:

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

在Compose中,咱们可以界说TextStyle目标,以界说设置一些文本的款式所需的信息。下面是其特点的示例:

data class TextStyle(
    val color: Color = Color.Unset,
    val fontSize: TextUnit = TextUnit.Inherit,
    val fontWeight: FontWeight? = null,
    val fontStyle: FontStyle? = null,
    val fontFamily: FontFamil? = null,
    val letterSpacing: TextUnit = TextUnit.Inherit,
    val background: Color = Colir.Unser,
    val textAlign = TextAlign? = null,
    val textDirection: TextDirection? = null,
    val lineHeight: TextUnit = TextUnit.Inherit,
    ...
)

theme软件包中创立一个新文件Typography.kt。首要,咱们将界说FOntFamily

private val Montserrat = FontFamily(
    Font(R.font.montserrat_regular),
    Font(R.font.montserrat_medium, FontWeight.W500).
    Font(R.font.montserrat_semibole, FontWeight.W600)
)
private val Domine = FontFamily(
    Font(R.font.domine_regular),
    Font(R.font.domine_bold, FontWeight.Bold)
)

现在创立一个MaterialTheme接受的Typography目标,为份额中的每个语义款式指定TextStyle:

val JetnewsTypography = Typography(
    h4 = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W600,
        fontSize = 30.sp
    ),
    h5 = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W600,
        fontSize = 24.sp
    ),
    h6 = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W600,
        fontSize = 20.sp
    ),
    subtitle1 = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W600,
        fontSize = 16.sp
    ),
    subtitle2 = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W500,
        fontSize = 14.sp
    ),
    body1 = TextStyle(
        fontFamily = Domine,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp
    ),
    body2 = TextStyle(
        fontFamily = Montserrat,
        fontSize = 14.sp
    ),
    button = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W500,
        fontSize = 14.sp
    ),
    caption = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.Normal,
        fontSize = 12.sp
    ),
    overline = TextStyle(
        fontFamily = Montserrat,
        fontWeight = FontWeight.W500,
        fontSize = 12.sp
    )
)

翻开Theme.kt并更新JetnewsTheme可组合项,以运用新的Typography:

@Composable
fun JetnewsTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        color = LightColors,
+       typography = JetnewsTypography,
        content = content
    )
}

翻开Home.kt并刷新预览,以检查显现精选博文的Card怎么反映新运用的形状主题。

3.5、深色主题

在运用中支撑深色主题不仅有助于您的运用在用户设备上更好地集成(从Android 10开始,设备上已供给大局深色主题切换开关),还有助于下降能耗以及满意无障碍功能需求供给支撑。Material供给了关于怎么创立深色主题的规划攻略。以下是咱们想为深色主题完成的备用调色板:

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)

翻开Color.kt并增加以下色彩:

val Red200 = Color(0xfff297a4)
val Red300 = Color(0xffea6d7e)

现在,翻开Theme.kt并增加以下代码:

private val DarkColors = darkColors(
    primary = Red300,
    primaryVariant = Red700,
    onPrimary = Color.Black,
    secondary = Red300,
    onSecondary = Color.Black,
    error = Red200
)

现在,更新HetnewsTheme:

@Composable
fun JetnewsTheme(
+   darkTheme: Boolean = isSystemInDakTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
+      colors = if (darkTheme) DarkColors else LightColors,
        typography = JetnewsTypography,
        shapes = JetnewsShapes,
        content = content
    )
}

此刻,咱们现已增加了用于判别是否运用深色主题的新形参,并将其默许设置为产讯设备的大局设置。这样即可为咱们供给很实用的默许值,但假如咱们要让特定屏幕始终/永不选用深色主题,或要让@Preview选用深色主题,咱们仍可轻松轻松替换。

翻开Homt.kt并为FeaturedPost可组合项创新的预览,此预览可以以深色主题显现该可组合项:

@Preview("Featured Post  Dark")
@Composable
private fun FeaturedPostDarkPreview() {
    val post = remember { PostRepo.getFeaturedPost() }
    JetnewsTheme(darkTheme = true) {
        FeaturedPost(post = post)
    }
}

刷新预览窗格以检查深色主题预览。

Jetpack Compose(第五趴)——Jetpack Compose主题设置(上)