如何应用Material Design 3和Material You

描述

 

  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 库的更新,其中包括更广泛的色调颜色、对组件的最新更新,甚至包括动态配色以使应用更加个性化,从而使其更加美观。

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

  •  
implementation 'androidx.compose.material31.0.0-alpha01'
  MaterialTheme

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

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

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

  上面这些颜色取自一组色调调色板,例如,我们来看一下 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 颜色槽。

  要实现 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 内容并为应用提供主题。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
@Composablefun JetchatTheme (    dark: Boolean = isSystemInDarkTheme(),    content: @Composable () -> Unit) {    val colorScheme = if (dark) JetchatDarkColorScheme else JetchatLightColorScheme    MaterialTheme (        colorScheme = colorScheme,        content = content,    )}
 
  下面让我们看一下 Jetchat 对话界面,界面中的不同部分使用了配色方案中的不同颜色槽。例如,根据用户不同,消息头像的边框颜色使用 Primary 颜色或 Tertiary 颜色。这里使用 MaterialTheme.colorScheme 访问主题颜色值。
  •  
  •  
  •  
  •  
  •  
  •  
  •  
@Composablefun Message(...) {    val avatarBorderColor = if (isUserMe) {        MaterialTheme.colorScheme.primary    } else {        MaterialTheme.colorScheme.tertiary    }    ...}
 

  动态配色

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

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

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
val dynamic = Build.VERSION.SOK_INT >= Build.VERSION_CODES.Sval 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 可组合项。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
@Composablefun 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 适配而来的文本样式。样式的命名和分组简化为显示、大标题、标题、正文和标签;每个分组都有大号、中号和小号字体。

  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:

  我们首先使用 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 表示访问主题字体值。

  •  
  •  
  •  
  •  
  •  
  •  
@Composablefun Message(...) {    …    Text (style = MaterialTheme.typography.titleMedium, ...)    Text (style = MaterialTheme.typography.labelSmall, ...)}

 

  高度

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

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

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

  组件更新

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

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

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// Materail 2 中的 NavigationBarimport androidx.compose.material.BottomNavigation @Composablefun BottomNavigation (    // M2 默认值    backgroundColor: Color,     elevation: Dp,)  // Materail 3 中的 NavigationBarimport androidx.compose.material3.NavigationBar @Composablefun 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.ExtendedFloatingActionButtonimport androidx.compose.material.Iconimport 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.ExtendedFloatingActionButtonimport androidx.compose.material3.Iconimport androidx.compose.material3.Text ExtendedFloatingActionButton(    icon = { Icon(...) },    text = { Text(...) },    containerColor = MaterialTheme.colorScheme.tertiary,    ...)

 

  视觉效果

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

   
  •  
  •  
  •  
  •  
  •  
  •  
// 拉伸滚动// 适用于 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 主题兼容。

  尾声

  现在是在您的 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

  文章出处:【微信公众号:谷歌开发者】欢迎添加关注!文章转载请注明出处。

  审核编辑:汤梓红


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分