美文网首页
实战 | 在应用中使用 Compose Material 3

实战 | 在应用中使用 Compose Material 3

作者: 谷歌开发者 | 来源:发表于2022-02-14 14:34 被阅读0次

    Material You 是下一代 Material Design 的发展方向,也是一种全新的设计愿景: 方便您打造个性化的样式设计、满足各种需求并自适应各种屏幕;Jetpack Compose 是用于构建原生 Android 界面的新款现代工具包,可以帮助您更快地构建更出色的应用。

    您可能对现有的 Compose Material 库十分了解,它基于 Material Design 2 规范,其中包括了 Material 主题、Material 组件和深色主题等功能。新的 Compose Material 3 Jetpack 库 现已发布 Alpha 版,它基于 Material Design 3 规范,包括了更新后的主题、组件以及动态配色这类 Material You 个性化功能,旨在与新的 Android 12 视觉样式和系统界面相得益彰。接下来,我们将使用 Jetchat 来说明如何应用 Material Design 3 和 Material You。

    如果您更喜欢通过视频了解此内容,请 点击此处 查看。

    Jetchat 是一款使用 Jetpack Compose 构建的示例聊天应用,目前使用 Material Design 2 中的主题和组件。我们将在 Jetchat 中,应用由我们的设计人员提供的 Compose Material 3 库的更新,其中包括更广泛的色调颜色、对组件的最新更新,甚至包括动态配色以使应用更加个性化,从而使其更加美观。

    △ Jetchat 应用

    在开始前,我们首先要将 Material 3 的依赖项添加到模块的 build.gradle 文件中:

    implementation 'androidx.compose.material3:material3:1.0.0-alpha01'
    

    MaterialTheme

    我们先来看看 MaterialTheme。现有的 MaterialTheme 可组合项是 Material Design 2 的实现,它通过调整颜色、排版和形状系统,可以在整个应用内实现对 Material 2 组件进行主题设置。我们为 Material Design 3 引入了新版本的 MaterialTheme,可以通过调整配色方案和排版系统对 Material 3 组件的主题进行设置,而更新 Shape 的功能也会在不久之后加入。

    import androidx.compose.material3.MaterialTheme
     
    @Composable
    fun MaterialTheme (
        colorScheme: ColorScheme,
        typography: Typography,
        // 更新 Shape 的功能即将到来
        content: @Composable () -> Unit
    )
    

    首先,我们看一下配色方案。Material Design 3 将颜色细分到特定名称的颜色槽中。比如 Material 3 组件使用的 Primary、Background 和 Error,这些颜色槽共同形成一种配色方案。部分颜色槽来自 Material Design 2,同时也引入了一些新的颜色槽以扩充整体调色板。这些颜色槽都包含了美观的全新默认基准颜色,在浅色和深色主题上都可以应用。

    △ 绿色框为 Material You 中新加入的颜色槽

    上面这些颜色取自一组色调调色板,例如,我们来看一下 Primary 颜色槽。该颜色槽使用的颜色值来自 Primary 色调调色板中的不同色调,并根据浅色和深色主题选择相应的色调,以满足无障碍功能要求。

    △ Primary 颜色槽

    Compose 使用新的 ColorScheme 类对此进行建模,其参数以 Material Design 3 配色方案中的颜色槽命名。您可以使用 lightColorScheme 函数创建具有浅色基准值的 ColorScheme 实例;也可以使用自定义颜色覆盖默认值,或者使用 darkColorScheme 设置深色默认基准值;您还可以使用 isSystemInDarkTheme 工具函数,根据系统设置在浅色和深色配色方案之间切换。

    val AppLightColorScheme = lightColorScheme (
        primary = Color(...),
        // secondary、tertiary 等等
        // 具有浅色基准值的 ColorScheme 实例
    )
     
    val AppDarkColorScheme = darkColorScheme(
        // primary、secondary、tertiary 等等
        // 具有深色基准值的 ColorScheme 实例
    )
     
    val dark = isSystemInDarkTheme()
    val colorScheme = if (dark) AppDarkColorScheme else AppLightColorScheme
     
    // 将 colorScheme 作为参数传递给 MaterialTheme。
    MaterialTheme (
        colorScheme = colorScheme,
        // 字型
    ) {
        // 应用内容
    }
    

    接下来,我们来看看 Jetchat 的配色方案。Jetchat 的配色方案由 MaterialTheme Builder 工具生成,我们使用 Jetchat 品牌颜色中的蓝色和黄色作为 Primary 颜色、Secondary 颜色和 Tertiary 颜色的来源,生成了非常适合 Jetchat 的 Material 3 配色方案,其中涵盖了用于浅色和深色主题的颜色。Jetchat 所使用的品牌颜色取自 MaterialTheme Builder 工具生成的一组自定义色调调色板,下图中显示了 Primary 颜色,即蓝色的色调调色板,以及配色方案中匹配的 Primary 颜色槽。

    △ MaterialTheme Builder 工具中生成的 Jetchat 配色方案

    要实现 Jetchat 配色方案,首先使用 Color 类声明这些颜色。MaterialTheme Builder 工具还可以为您导出生成的代码。接下来,便可以使用相应的颜色值声明 Jetchat 浅色和深色配色方案。

    // 来自名为'Blue'的色调调色盘的 Primary 颜色
    val Blue10 = Color (0xFF000965)
    val Blue20 = Color (0xFF00159E)
    val Blue30 = Color (0xFF0023DA)
    val Blue40 = Color (0xFF1E40FF)
    val Blue80 = Color (0xFFBBC3FF)
    val Blue90 = Color (0xFFDDE0FF)
     
    val JetchatLightColorScheme = lightColorScheme (
        primary = Blue40,
        onPrimary = Color.White,
        primaryContainer = Blue90,
        onPrimaryContainer = Blue10,
        // secondary、tertiary、surface 等等
    )
     
    val JetchatDarkColorScheme = darkColorScheme (
        primary = Blue80,
        onPrimary = Blue20,
        primaryContainer = Blue30,
        onPrimaryContainer = Blue90,
        // secondary、tertiary、surface 等等
    )
    

    我们为 Jetchat 主题创建了一个新的可组合函数,该函数接收一个用于判断深色主题的参数和一个应用内容参数,从而使我们可以在 Jetchat 的浅色和深色配色方案之间切换。接下来,我们将 colorScheme 值和 content 传递给内部的 MaterialTheme 可组合项,这使我们能够封装 Jetchat 内容并为应用提供主题。

    @Composable
    fun JetchatTheme (
        dark: Boolean = isSystemInDarkTheme(),
        content: @Composable () -> Unit
    ) {
        val colorScheme = if (dark) JetchatDarkColorScheme else JetchatLightColorScheme
        MaterialTheme (
            colorScheme = colorScheme,
            content = content,
        )
    }
    

    下面让我们看一下 Jetchat 对话界面,界面中的不同部分使用了配色方案中的不同颜色槽。例如,根据用户不同,消息头像的边框颜色使用 Primary 颜色或 Tertiary 颜色。这里使用 MaterialTheme.colorScheme 访问主题颜色值。

    △ Jetchat 对话界面
    @Composable
    fun Message(...) {
        val avatarBorderColor = if (isUserMe) {
            MaterialTheme.colorScheme.primary
        } else {
            MaterialTheme.colorScheme.tertiary
        }
        ...
    }
    

    动态配色

    接下来,让我们来了解什么是动态配色。动态配色是 Material You 的重要部分,即用算法从用户的壁纸中提取自定义颜色并应用于应用和系统界面,您可将此作为起点来生成完整的浅色和深色配色方案。

    △ Jetchat 的配色方案随用户设置的壁纸变化

    动态配色可在 Android 12 及更高版本中使用,要在 Compose 中实现动态 ColorScheme,需要首先检查 Build.VERSION.SDK。如果动态配色可用,我们便可以设置动态 ColorScheme;如果不可用,则可以回退到像以前一样使用 lightColorScheme 或 darkColorScheme:

    val dynamic = Build.VERSION.SOK_INT >= Build.VERSION_CODES.S
    val colorScheme = if (dynamic) {
        val context = LocalContext.current
        // 使用 dynamicLightColorScheme 函数创建具有浅色动态值的 ColorScheme 实例
        // 或使用 dynamicDarkColorScheme 创建具有深色动态值的实例
        // 传入 Context 以便从 Android 系统获取动态配色资源
        if (dark) dynamiclightColorScheme(context) else dynamicDarkColorScheme(context)
    } else {
        // 使用 lightColorScheme 或者 darkColorScheme
    }
    

    目前,Jetchat 一直在使用品牌的蓝色配色方案,但我们希望增加对基于壁纸的动态配色方案的支持,以配合用户的个性化调整。在本例中,色调调色板基于壁纸中的颜色生成,而动态配色方案则派生自这些色调调色板,其中包括用于浅色和深色主题的颜色。

    为了在 Jetchat 中实现这一点,我们首先更新 JetchatTheme 为动态配色添加一个新参数,然后使用该动态配色参数设置动态 ColorScheme,或者在不可用时回退到品牌的蓝色配色方案。与前面一样将 colorScheme 值和 content 传递给内部的 MaterialTheme 可组合项。

    @Composable
    fun JetchatTheme (
        dark: Boolean = isSystemInDarkTheme (),
        dynamic: Boolean = Build. VERSION.SDK_INT >= Build.VERSION_CODES.S,
        content: @Composable () -> Unit
    ) {
        // ColorScheme 配置以及 MaterialTheme
        val colorScheme = if (dynamic) {
            val context = LocalContext.current
            if (dark) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        } else {
            if (dark) JetchatDarkColor Scheme else Jetchat Light Color Scheme
        }
     
        MaterialTheme(
            colorScheme = colorScheme, 
            content = content,
        )
    }
    

    现在,在 Android 12 及更高版本上,Jetchat 界面可根据用户壁纸自动调整配色,无论是浅色主题还是深色主题都可提供适合品牌的美观体验。

    △ 自动适配深浅色主题的动态配色

    排版

    现在我们已经了解了配色方案,接下来让我们来看看排版。Material Design 3 有了新的字体规格,包括了由 Material Design 2 适配而来的文本样式。样式的命名和分组简化为显示、大标题、标题、正文和标签;每个分组都有大号、中号和小号字体。

    △ Material 3 与 Material 2 的字体样式分组

    Compose 使用新的 Typography 类对字体规格进行建模,其参数以 Material Design 3 字体规格中的样式命名。我们可以使用 Roboto 基准值创建一个 Typography 实例,用自定义文本样式覆盖默认值,最后将 Typography 作为参数传递给 MaterialTheme。

    import androidx.compose.material3.Typography
     
    class Typography (
        val displayLarge: TextStyle,
        val displayMedium: TextStyle,
        val displaySmall: TextStyle,
        // headlineLarge、titleMedium、bodySmall 等等
    )
     
    val AppTypography = Typography (
        bodyLarge = TextStyle(...),
        // displayLarge、titleMedium、labelSmall 等等
        // 使用默认的 Roboto 基准值
    )
     
    MaterialTheme (
        typography = AppTypography,
        // colorScheme
    ) {
        //App content
    }
    

    我们再来看看 Jetchat 的排版。设计人员为我们提供了新的品牌字体规格,用到了自定义字体 Montserrat 和 Karla:

    △ Jetchat 所使用的字体规格

    我们首先使用 FontFamily 类声明这些字体,该类将保存 Font 类的实例。我们可以使用字体资源 ID 和字体粗细构造 Font 类,然后使用 Typography 类声明 Jetchat 字体样式,并使用 TextStyle 类覆盖每个文本样式,包括我们的字体、字号、字体粗细等其他排版值。最后,同样的,将 Typography 作为参数传递给 MaterialTheme:

    val MontserratFontFamily = FontFamily ( 
        Font(R.font.montserrat_regular),
        Font(R.font montserrat_light, FontWeight Light),
        Font(R.font.montserrat_semibold, FontWeight. SemiBold)
    )
     
    val KarlaFontFamily = FontFamily (
        Font(R.font.karla_regular),
        Font(R.font.karla_bold, FontWeight. Bold)
    )
     
    val JetchatTypography = Typography( 
        bodyLarge = TextStyle(
            fontFamily = KarlaFontFamily,
            fontWeight = FontWeight. Normal,
            fontSize = 16.sp,
            lineHeight = 24.sp,
            letterSpacing = 0.15.sp
        ),
     
        // titleMedium、labelSmall 等等
    )
     
    MaterialTheme (
        typography = JetchatTypography,
        // colorScheme、content
    )
    

    我们来看一下 Jetchat 对话界面,界面中的每个部分使用了 Jetchat 字体规格中的不同文本样式。例如,消息中的联系人和时间戳,分别使用了 titleMedium 和 labelSmall 样式。它们通过 MaterialTheme.typography 表示访问主题字体值。

    △ 对话界面的字体设置
    @Composable
    fun Message(...) {
        …
        Text (style = MaterialTheme.typography.titleMedium, ...)
        …
        Text (style = MaterialTheme.typography.labelSmall, ...)
    }
    

    高度

    在了解了 Material 3 主题相关的更新后,接下来让我们看看 Material Design 另一个关键更新——高度。概括来说,Material 2 中使用阴影表示高度,而 Material 3 中改为使用色调颜色叠加层表示高度。这是一种区分容器和表面的新方式,增加色调高度会使色调变得更为突出。

    在 Material 2 中高度叠加层是深色主题的一部分,在 Material 3 中也已更改为色调颜色叠加层。

    △ M2 与 M3 中高度系统效果对比

    我们以 Surface 组件为例,Surface 是用于支持大多数 Material 组件的可组合项,现有的 Surface 可组合项实现的是 Material Design 2 的高度系统。在 Material Design 2 中 Surface 接收一个 elevation 参数并处理深色主题中的阴影和叠加层渲染。我们为 Material Design 3 引入了新版 Surface,它接受一个 tonalElevation 参数,并会在浅色和深色主题中处理色调颜色叠加层渲染。让我们看看前后有何不同:

    △ Material 2 中的 Surface △ Material 3 中的 Surface

    组件更新

    Material 3 对许多组件进行了更新,比如按钮、应用栏、对话框、FAB 和导航组件。此类更新利用了新的 Material 3 主题设置值,并包含了对每个组件规范的最新更新。

    △ Material 3 中更新的组件

    例如 Material 2 中的 BottomNavigation。它符合 Material Design 2 规范,并接受 backgroundColor 和 elevation 等参数。在 Material 3 中该可组合项更名为 NavigationBar,它符合 Material Design 3 规范,其中的参数更改为 containerColor 和 tonalElevation,以更准确地反映各自的用途。

    // Materail 2 中的 NavigationBar
    import androidx.compose.material.BottomNavigation
     
    @Composable
    fun BottomNavigation (
        // M2 默认值
        backgroundColor: Color, 
        elevation: Dp,
        …
    )
     
     
    // Materail 3 中的 NavigationBar
    import androidx.compose.material3.NavigationBar
     
    @Composable
    fun NavigationBar (
        // M3 默认值
        containerColor: Color, 
        tonalElevation: Dp,
        …
    )
    
    △ 更新前后的样式改变

    Compose Material 3 中的组件进行了很多更新,为了让您全面了解所有的组件以及它们的实现方式,我们更新了 Compose Material Catalog 应用,并新增了 Material 3 部分。请在 AOSP 上查看 源代码 并在 Google Play 中下载该应用

    下面我们来看看 Jetchat 中的一个例子。在个人资料界面上有一个用于撰写消息的扩展 FAB,该组件已从 Material 2 更新为 Material 3 版本。这是 Material 2 版本的一个简单实现,使用了 ExtendedFloatingActionButton 可组合项,内部使用了 Icon 和 Text、可组合项以及自定义的 Primary 背景颜色。

    import androidx.compose.material.ExtendedFloatingActionButton
    import androidx.compose.material.Icon
    import androidx.compose.material.Text
     
    ExtendedFloatingActionButton(
        icon = { Icon(...) },
        text = { Text(...) },
        backgroundColor = MaterialTheme.colors.primary,
        ...
    )
    

    Material 3 对该组件的更新如这里所示,可组合项的依赖导入已更改为 Material 3,我们使用更名后的 containerColor 参数和 Material 3 配色方案中的 Tertiary 颜色。

    import androidx.compose.material3.ExtendedFloatingActionButton
    import androidx.compose.material3.Icon
    import androidx.compose.material3.Text
     
    ExtendedFloatingActionButton(
        icon = { Icon(...) },
        text = { Text(...) },
        containerColor = MaterialTheme.colorScheme.tertiary,
        ...
    )
    

    视觉效果

    Material You 的某些方面来自新的 Android 12 视觉样式和系统界面,其中的两个重要变化是波纹和滚动效果。现在,波纹效果会在按下时使用细微的闪光照亮表面,滚动效果则会在滚动容器的边缘使用拉伸效果。实现这些更改不需要额外的工作,在 Compose Foundation 1.1 及更高版本的滚动容器可组合项中拉伸滚动默认处于开启状态;Android 12 上提供的闪光波纹适用于所有 Material 组件。

    △ M2 与 M3 中的波纹效果
    // 拉伸滚动
    // 适用于 LazyColumn、Lazy Row、LazyVerticalGrid 等组件
    // ComposeFoundation 1.1.0+ 可用
     
    // 闪光波纹
    // 适用于所有 Material 2 和 Material 3 组件
    // Android 12+ 可用
    

    与 Android View 的互操作性改进

    与 Android 视图的互操作性是使用 Compose 开发应用的一个重要部分,我们已经在 Material 3 中进行了一些更新来支持这一点。MDC-AndroidCompose Theme Adapter 库 是一款支持重用 Android XML 主题的 Material 组件,以方便我们在 Jetpack Compose 中设置主题。

    现有的 MdcTheme 可组合项与 Material 2 XML 主题兼容,我们还引入了一个新的 Mdc3Theme 可组合项,它与 Material 3 XML 主题兼容。

    △ MDC-AndroidCompose Theme Adapter 是 XML 主题与 MaterialTheme 之间的桥梁

    尾声

    现在是在您的 Android 应用中试用 Compose Material 3 的好时机,我们准备了一系列资源来帮助您顺利完成旅程。我们提供了新的关于 Compose Material 3 的 API 文档,并在 Android Studio 中提供了新的 Empty Compose Activity 模板,其中包含有关 Material 3 的更新。此外,我们还更新了 Compose 中的主题设置 指南,以及在前面看到的 Jetchat 示例和 Compose Material Catalog 应用,以及 MDC-Android ComposeTheme Adapter 互操作性库。

    相关文章

      网友评论

          本文标题:实战 | 在应用中使用 Compose Material 3

          本文链接:https://www.haomeiwen.com/subject/pdmclrtx.html