在 Compose for Wear OS 中从 Material 2.5 迁移到 Material 3

Material 3 Expressive 是 Material Design 的下一个演进版本。它包括更新的主题、组件和个性化功能,例如动态颜色。

本指南重点介绍将应用从 Wear Compose Material 2.5 (androidx.wear.compose) Jetpack 库迁移到 Wear Compose Material 3 (androidx.wear.compose.material3) Jetpack 库。

方法

要将应用代码从 M2.5 迁移到 M3,请遵循 Compose Material 迁移手机指南中描述的相同方法,特别是:

依赖项

M3 具有与 M2.5 不同的软件包和版本

M2.5

implementation("androidx.wear.compose:compose-material:1.4.0")

M3

implementation("androidx.wear.compose:compose-material3:1.5.0-beta03")

请参阅 Wear Compose Material 3 版本页面上的最新 M3 版本。

Wear Compose Foundation 库版本 1.5.0-beta01 引入了一些旨在与 Material 3 组件配合使用的新组件。同样,Wear Compose Navigation 库中的 SwipeDismissableNavHost 在 Wear OS 6 (API 级别 36) 或更高版本上运行时具有更新的动画。更新到 Wear Compose Material 3 版本时,我们建议同时更新 Wear Compose Foundation 和 Navigation 库

implementation("androidx.wear.compose:compose-foundation:1.5.0-beta03")
implementation("androidx.wear.compose:compose-navigation:1.5.0-beta03")

主题

在 M2.5 和 M3 中,主题可组合项都命名为 MaterialTheme,但导入的包和参数有所不同。在 M3 中,Colors 参数已重命名为 ColorScheme,并引入了 MotionScheme 用于实现过渡。

M2.5

import androidx.wear.compose.material.MaterialTheme

MaterialTheme(
        colors = AppColors,
        typography = AppTypography,
        shapes = AppShapes,
        content = content
)

M3

import androidx.wear.compose.material3.MaterialTheme

MaterialTheme(
        colorScheme = AppColorScheme,
        typography = AppTypography,
        shapes = AppShapes,
        motionScheme = AppMotionScheme,
        content = content
)

颜色

M3 中的颜色系统与 M2.5 显著不同。颜色参数的数量增加了,它们的名称不同,并且它们与 M3 组件的映射方式也不同。在 Compose 中,这适用于 M2.5 Colors 类、M3 ColorScheme 类以及相关函数

M2.5

import androidx.wear.compose.material.Colors

val appColorScheme: Colors = Colors(
   // M2.5 Color parameters
)

M3

import androidx.wear.compose.material3.ColorScheme

val appColorScheme: ColorScheme = ColorScheme(
   // M3 ColorScheme parameters
)

下表描述了 M2.5 和 M3 之间的主要区别

M2.5

M3

颜色

已重命名为 ColorScheme

13 种颜色

28 种颜色

不适用

新的动态颜色主题

不适用

新的第三色调,更具表现力

动态颜色主题

M3 中的一个新功能是动态颜色主题。如果用户更改表盘颜色,UI 中的颜色也会随之变化。

使用 dynamicColorScheme 函数实现动态配色方案,并提供 defaultColorScheme 作为动态配色方案不可用时的备用方案。

@Composable
fun myApp() {
  val myColorScheme = myBrandColors()
  val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
  MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {...}
}

排版

M3 中的排版系统与 M2 不同,它包括以下功能

  • 九种新的文本样式
  • 弹性字体,允许自定义不同字重、字宽和圆角的类型比例
  • AnimatedText,它使用弹性字体

M2.5

import androidx.wear.compose.material.Typography

val Typography = Typography(
   // M2.5 TextStyle parameters
)

M3

import androidx.wear.compose.material3.Typography

val Typography = Typography(
   // M3 TextStyle parameters
)

弹性字体

弹性字体允许设计师指定特定尺寸的字体宽度和字重。

文本样式

以下文本样式在 M3 中可用。M3 的各种组件默认使用这些样式。

排版

文本样式

显示

displayLarge、displayMedium、displaySmall

标题

titleLarge、titleMedium、titleSmall

标签

labelLarge、labelMedium、labelSmall

正文

bodyLarge、bodyMedium、bodySmall、bodyExtraSmall

数字

numeralExtraLarge、numeralLarge、numeralMedium、numeralSmall、numeralExtraSmall

弧形

arcLarge、arcMedium、arcSmall

形状

M3 中的形状系统与 M2 不同。形状参数的数量增加了,它们的命名不同,并且它们与 M3 组件的映射方式也不同。以下形状尺寸可用

  • 超小
  • 超大

在 Compose 中,这适用于 M2 Shapes 类和 M3 Shapes

M2.5

import androidx.wear.compose.material.Shapes

val Shapes = Shapes(
   // M2.5 Shapes parameters
)

M3

import androidx.wear.compose.material3.Shapes

val Shapes = Shapes(
   // M3 Shapes parameters
)

使用 从 Material 2 迁移到 Compose 中的 Material 3 中的 Shapes 参数映射作为起点。

形状变形

M3 引入了形状变形:形状现在会根据交互进行变形。

形状变形行为可作为多种圆形按钮的变体,请参见下文

按钮

形状变形功能

IconButton

IconButtonDefaults.animatedShape() 在按下时为图标按钮添加动画

IconToggleButton

IconToggleButtonDefaults.animatedShape() 在按下时为图标切换按钮添加动画

IconToggleButtonDefaults.variantAnimatedShapes() 在按下和选中/取消选中时为图标切换按钮添加动画

TextButton

TextButtonDefaults.animatedShape() 在按下时为文本按钮添加动画

TextToggleButton

TextToggleButtonDefaults.animatedShapes() 在按下时为文本切换按钮添加动画,TextToggleButtonDefaults.variantAnimatedShapes() 在按下和选中/取消选中时为文本切换按钮添加动画

组件和布局

M2.5 中的大多数组件和布局在 M3 中都可用。但是,一些 M3 组件和布局在 M2.5 中不存在。此外,一些 M3 组件比其在 M2.5 中的等效组件有更多的变体。

虽然某些组件需要特殊考虑,但以下函数映射建议作为起点

Material 2.5

Material 3

androidx.wear.compose.material.dialog.Alert

androidx.wear.compose.material3.AlertDialog

androidx.wear.compose.material.Button

androidx.wear.compose.material3.IconButtonandroidx.wear.compose.material3.TextButton

androidx.wear.compose.material.Card

androidx.wear.compose.material3.Card

androidx.wear.compose.material.TitleCard

androidx.wear.compose.material3.TitleCard

androidx.wear.compose.material.AppCard

androidx.wear.compose.material3.AppCard

androidx.wear.compose.material.Checkbox

无 M3 等效项,迁移到 androidx.wear.compose.material3.CheckboxButtonandroidx.wear.compose.material3.SplitCheckboxButton

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.Button
androidx.wear.compose.material3.OutlinedButton
androidx.wear.compose.material3.FilledTonalButton
androidx.wear.compose.material3.ChildButton

androidx.wear.compose.material.CompactChip

androidx.wear.compose.material3.CompactButton

androidx.wear.compose.material.InlineSlider

androidx.wear.compose.material3.Slider

androidx.wear.compose.material.LocalContentAlpha

已删除,因为 Material 3 中的 TextIcon 未使用

androidx.wear.compose.material.PositionIndicator

androidx.wear.compose.material3.ScrollIndicator

androidx.wear.compose.material.RadioButton

无 M3 等效项,迁移到 androidx.wear.compose.material3.RadioButtonandroidx.wear.compose.material3.SplitRadioButton

androidx.wear.compose.material.SwipeToRevealCard

androidx.wear.compose.material3.SwipeToReveal

androidx.wear.compose.material.SwipeToRevealChip

androidx.wear.compose.material3.SwipeToReveal

android.wear.compose.material.Scaffold

androidx.wear.compose material3.AppScaffoldandroidx.wear.compose.material3.ScreenScaffold

androidx.wear.compose.material.SplitToggleChip

无 M3 等效项,迁移到 androidx.wear.compose.material3.SplitCheckboxButton androidx.wear.compose.material3.SplitSwitchButtonandroidx.wear.compose.material3.SplitRadioButton

androidx.wear.compose.material.Switch

无 M3 等效项,迁移到 androidx.wear.compose.material3.SwitchButtonandroidx.wear.compose.material3.SplitSwitchButton

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.IconToggleButtonandroidx.wear.compose.material3.TextToggleButton

androidx.wear.compose.material.ToggleChip

androidx.wear.compose.material3.CheckboxButton
androidx.wear.compose.material3.RadioButton
androidx.wear.compose.material3.SwitchButton

androidx.wear.compose.material.Vignette

已删除,因为 Material 3 Expressive 设计中不包含用于 Wear OS 的该组件

以下是所有 Material 3 组件的完整列表

Material 3

Material 2.5 等效组件(如果 M3 中不是新增组件)

androidx.wear.compose.material3.AlertDialog

androidx.wear.compose.material.dialog.Alert

androix.wear.compose.material3.AnimatedPage

androidx.wear.compose.material3.AnimatedText

androidx.wear.compose material3.AppScaffold

android.wear.compose.material.Scaffold (与 androidx.wear.compose.material3.ScreenScaffold)

androidx.wear.compose.material3.Button

androidx.wear.compose.material.Chip

androidx.wear.compose.material3.ButtonGroup

androidx.wear.compose.material3.Card

androidx.wear.compose.material.Card

androidx.wear.compose.material3.CheckboxButton

带复选框切换控件的 androidx.wear.compose.material.ToggleChip

androidx.wear.compose.material3.ChildButton

androidx.wear.compose.material.Chip(仅当不需要背景时)

androidx.wear.compose.material3.CircularProgressIndicator

androidx.wear.compose.material.CircularProgressIndicator

androidx.wear.compose.material3.CompactButton

androidx.wear.compose.material.CompactChip

androidx.wear.compose.material3.ConfirmationDialog

androidx.wear.compose.material.dialog.Confirmation

androidx.wear.compose.material3.curvedText

androidx.wear.compose.material.curvedText

androidx.wear.compose.material3.DatePicker

androidx.wear.compose.material3.Dialog

androidx.wear.compose.material.dialog.Dialog

androidx.wear.compose.material3.EdgeButton

androidx.wear.compose.material3.FadingExpandingLabel

androidx.wear.compose.material3.FilledTonalButton

需要色调按钮背景时的 androidx.wear.compose.material.Chip

androidx.wear.compose.material3.HorizontalPageIndicator

androidx.wear.compose.material.HorizontalPageIndicator

androidx.wear.compose.material3.HorizontalPagerScaffold

androidx.wear.compose.material3.Icon

androidx.wear.compose.material.Icon

androidx.wear.compose.material3.IconButton

androidx.wear.compose.material.Button

androidx.wear.compose.material3.IconToggleButton

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.LevelIndicator

androidx.wear.compose.material3.LinearProgressIndicator

androidx.wear.compose.material3.ListHeader

androidx.wear.compose.material.ListHeader

androidx.wear.compose.material3.ListSubHeader

androidx.wear.compose.material3.MaterialTheme

androidx.wear.compose.material.MaterialTheme

androidx.wear.compose.material3.OpenOnPhoneDialog

androidx.wear.compose.material3.Picker

androidx.wear.compose.material.Picker

androidx.wear.compose.material3.PickerGroup

androidx.wear.compose.material.PickerGroup

androix.wear.compose.material3.RadioButton

带单选按钮切换控件的 androidx.wear.compose.material.ToggleChip

androidx.wear.compose.material3.ScreenScaffold

android.wear.compose.material.Scaffold (与 androidx.wear.compose material3.AppScaffold)

androidx.wear.compose.material3.ScrollIndicator

androidx.wear.compose.material.PositionIndicator

androidx.wear.compose.material3.scrollaway

androidx.wear.compose.material.scrollaway

androidx.wear.compose.material3.SegmentedCircularProgressIndicator

androidx.wear.compose.material3.Slider

androidx.wear.compose.material.InlineSlider

androidx.wear.compose.material3.SplitRadioButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.SplitCheckboxButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.SplitSwitchButton

androidx.wear.compose.material.SplitToggleChip

androidx.wear.compose.material3.Stepper

androidx.wear.compose.material.Stepper

androidx.wear.compose.material3.SwipeToDismissBox

androidx.wear.compose.material.SwipeToDismissBox

androidx.wear.compose.material3.SwipeToReveal

androidx.wear.compose.material.SwipeToRevealCardandroidx.wear.compose.material.SwipeToRevealChip

androidx.wear.compose.material3.SwitchButton

带开关切换控件的 androidx.wear.compose.material.ToggleChip

androidx.wear.compose.material3.Text

androidx.wear.compose.material.Text

androidx.wear.compose.material3.TextButton

androidx.wear.compose.material.Button

androidx.wear.compose.material3.TextToggleButton

androidx.wear.compose.material.ToggleButton

androidx.wear.compose.material3.TimeText

androidx.wear.compose.material.TimeText

androidx.wear.compose.material3.VerticalPagerScaffold

最后是 Wear Compose Foundation 库版本 1.5.0-beta01 中的一些相关组件列表

Wear Compose Foundation 1.5.0-beta

androidx.wear.compose.foundation.hierarchicalFocusGroup

用于在应用程序中注释可组合项,以跟踪组合的活动部分并协调焦点。

androidx.compose.foundation.pager.HorizontalPager

一个水平滚动的寻呼机,基于 Compose Foundation 组件构建,并具有 Wear 特定的增强功能,以提高性能和符合 Wear OS 指南。

androidx.compose.foundation.pager.VerticalPager

一个垂直滚动的寻呼机,基于 Compose Foundation 组件构建,并具有 Wear 特定的增强功能,以提高性能和符合 Wear OS 指南。

androidx.wear.foundation.lazy.TransformingLazyColumn

可用于替代 ScalingLazyColumn,以向每个项目添加滚动变换效果。

按钮

M3 中的按钮与 M2.5 不同。M2.5 Chip 已被 Button 替换。Button 实现为 Text maxLinestextAlign 提供默认值。这些默认值可以在 Text 元素中覆盖。

M2.5

import androidx.wear.compose.material.Chip

//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)

M3

import androidx.wear.compose.material3.Button

//M3 Buttons
Button(...)
CompactButton(...)
IconButton(...)
TextButton(...)

M3 还包括新的按钮变体。请在 Compose Material 3 API 参考概览中查看它们。

M3 引入了一个新按钮:EdgeButtonEdgeButton 有 4 种不同尺寸:超小、小、中和大。EdgeButton 实现根据尺寸提供 maxLines 的默认值,可以自定义。

如果您正在使用 TransformingLazyColumnScalingLazyColumn,请将 EdgeButton 传递给 ScreenScaffold,使其随着滚动改变形状。请参阅以下代码,了解如何将 EdgeButtonScreenScaffoldTransformingLazyColumn 一起使用。

import androidx.wear.compose.material3.EdgeButton
import androidx.wear.compose.material3.ScreenScaffold

ScreenScaffold(
   scrollState = state,
   contentPadding = contentPadding,
   edgeButton = {
      EdgeButton(...)
   }
){ contentPadding ->
   TransformingLazyColumn(state = state, contentPadding = contentPadding,){
   // additional code here
   }
}

脚手架

M3 中的 Scaffold 与 M2.5 不同。在 M3 中,AppScaffold 和新的 ScreenScaffold 可组合项取代了 Scaffold。AppScaffoldScreenScaffold 布置屏幕结构并协调 ScrollIndicatorTimeText 组件的过渡。

AppScaffold 允许静态屏幕元素(如 TimeText)在应用内过渡(如滑动手势关闭)期间保持可见。它为主应用内容提供了一个插槽,该插槽通常由导航组件(如 SwipeDismissableNavHost)提供

您为 Activity 声明一个 AppScaffold,并为每个屏幕使用一个 ScreenScaffold

M2.5

import androidx.wear.compose.material.Scaffold

Scaffold {...}

M3

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.ScreenScaffold

AppScaffold {
   // Define the navigation hierarchy within the AppScaffold,
   // such as using SwipeDismissableNavHost.
   SwipeDismissableNavHost(...) {
      composable("home") {
         HomeScreen()
      }
      //other screens
   }
}
fun HomeScreen() {
    val scrollState = rememberScrollState()
    ScreenScaffold(scrollState = scrollState) {
    //rest of the screen code
    }
}

如果您正在使用带有 HorizontalPagerIndicatorHorizontalPager,您可以迁移到 HorizontalPagerScaffoldHorizontalPagerScaffold 放置在 AppScaffold 中。AppScaffoldHorizontalPagerScaffold 布置寻呼机的结构并协调 HorizontalPageIndicatorTimeText 组件的过渡。

HorizontalPagerScaffold 默认在屏幕的中心末端显示 HorizontalPageIndicator,并根据 Pager 是否正在分页来协调显示/隐藏 TimeTextHorizontalPageIndicator,这由 PagerState 决定。

还有一个新的 AnimatedPage 组件,它根据其位置为寻呼机中的页面添加缩放和蒙版效果动画。

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.HorizontalPager
import androidx.wear.compose.foundation.pager.rememberPagerState

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })

    HorizontalPagerScaffold(pagerState = pagerState) {
       HorizontalPager(
          state = pagerState,
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                ScreenScaffold {

   }
}

最后,M3 引入了一个 VerticalPagerScaffold,它遵循与 HorizontalPagerScaffold 相同的模式

import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.HorizontalPagerScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.foundation.pager.VerticalPager
import androidx.wear.compose.foundation.pager.rememberPagerState

AppScaffold {
   val pagerState = rememberPagerState(pageCount = { 10 })

   VerticalPagerScaffold(pagerState = pagerState) {
      VerticalPager(
         state = pagerState
      ) { page ->
             AnimatedPage(pageIndex = page, pagerState = pagerState){
                ScreenScaffold {
        
   }
}

占位符

M2.5 和 M3 之间有一些 API 更改。Placeholder.PlaceholderDefaults 现在提供了两个修饰符

有关 Placeholder 组件的其他更改,请参见下文。

M2.5

M3

PlaceholderState.startPlaceholderAnimation

已删除

PlaceholderState.placeholderProgression

已删除

PlaceholderState.isShowContent

已重命名为 !PlaceholderState.isVisible

PlaceholderState.isWipeOff

已删除

PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush

已删除

PlaceholderDefaults.placeholderBackgroundBrush

已删除

PlaceholderDefaults.placeholderChipColors

已删除

SwipeDismissableNavHost

SwipeDismissableNavHostwear.compose.navigation 的一部分。当此组件与 M3 一起使用时,M3 MaterialTheme 会更新 LocalSwipeToDismissBackgroundScrimColorLocalSwipeToDismissContentScrimColor

TransformingLazyColumn

TransformingLazyColumnwear.compose.lazy.foundation 的一部分,它增加了对列表项在滚动期间进行缩放和变形动画的支持,从而增强了用户体验。

ScalingLazyColumn 类似,它提供了 rememberTransformingLazyColumnState() 来创建在组合中记住的 TransformingLazyColumnState

要添加缩放和变形动画,请将以下内容添加到每个列表项:

  • Modifier.transformedHeight,允许您使用 TransformationSpec 计算项目的变换高度,除非您需要进一步自定义,否则可以使用 rememberTransformationSpec()
  • 一个 SurfaceTransformation
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.ScreenScaffold
import androidx.wear.compose.material3.SurfaceTransformation
import androidx.wear.compose.material3.lazy.rememberTransformationSpec
import androidx.wear.compose.material3.lazy.transformedHeight
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn

val state = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
AppScaffold {
   ScreenScaffold(state) { contentPadding ->
      TransformingLazyColumn(state = state, contentPadding = contentPadding) {
         items(count = 50) {
            Button(
               onClick = {},
               modifier =
                        Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),
                        transformation = SurfaceTransformation(transformationSpec),
                    ) {
                        Text("Item $it")
                    }
                }
            }
        }
    }

有用链接

要了解有关从 M2.5 迁移到 Compose 中的 M3 的更多信息,请查阅以下其他资源。

示例

API 参考和源代码

设计