jetpack-compose-m3
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrerequisites & Compatibility
前提条件与兼容性
-
Wear OS Compose Material3 version: If an internal tool is available to establish the latest stable versionof
{VERSION}, use that tool.androidx.wear.compose:compose-material3- Otherwise, fetch the official Maven metadata XML to identify (highest number, ignoring
{VERSION},-alpha, or-beta)-rc- Strict Compliance: If a version is listed as stable, you MUST use it, unless overridden by the user. Do not downgrade based on initial "Unresolved reference" errors in the editor or outdated web search results.
- Otherwise, fetch the official Maven metadata XML to identify
-
Kotlin Version: For Wear Compose Material3, use Kotlin 2.0.0 or higher.
-
Compose Compiler:
- If Kotlin version is 2.0.0+ , the project must use the Gradle plugin.
org.jetbrains.kotlin.plugin.compose - If Kotlin version is < 2.0.0 , the project must use in
kotlinCompilerExtensionVersion, matching the Compose to Kotlin Compatibility Map.composeOptions- Min SDK: Ensure is at least 25 (Wear OS 2.0).
minSdk
- Min SDK: Ensure
- If Kotlin version is 2.0.0+ , the project must use the
-
Sample Extraction Mandate: Wear Compose libraries ship with an additional JAR file which contains individual samples for each and every component. You MUST NOT propose code changes until the samples in Capabilityfiles are incomplete and NOT a substitute for these samples; bypassing extraction is an environment setup failure.
- Wear OS Compose Material3 版本: 如果有内部工具可获取 的最新稳定版本
androidx.wear.compose:compose-material3,请使用该工具。{VERSION}- 若没有,则获取官方Maven元数据XML来确定(选择最高版本号,忽略
{VERSION}、-alpha或-beta后缀的版本)-rc- 严格合规: 若列出了稳定版本,必须使用该版本,除非用户另行指定。请勿因编辑器初始出现的"未解析引用"错误或过时的网页搜索结果而降级版本。
- 若没有,则获取官方Maven元数据XML来确定
- Kotlin版本: 使用Wear Compose Material3时,需使用Kotlin 2.0.0或更高版本。
- Compose编译器:
- 若Kotlin版本为2.0.0+,项目必须使用 Gradle插件。
org.jetbrains.kotlin.plugin.compose - 若Kotlin版本**<2.0.0**,项目必须在中配置
composeOptions,版本需与Compose与Kotlin兼容性对照表匹配。kotlinCompilerExtensionVersion- 最低SDK版本: 确保至少为25(对应Wear OS 2.0)。
minSdk
- 最低SDK版本: 确保
- 若Kotlin版本为2.0.0+,项目必须使用
- 示例提取要求:Wear Compose库附带一个额外的JAR文件,其中包含每个组件的独立示例。在提取并查看这些示例之前,不得提出任何代码修改建议;Capability文件中的示例并不完整,无法替代这些官方示例,跳过提取步骤属于环境配置失败。
Gotchas
注意事项
- Mandatory Sync & Validation: After updating versions in or
libs.versions.toml, you must perform a Gradle sync before refactoring any code. This ensures the environment has resolved the libraries correctly.build.gradle.kts - Prohibition of Guessing (Error Protocol): If you encounter an 'Unresolved Reference' or API mismatch after a successful sync, do not attempt to 'fix' it by downgrading the library version.
- 必须同步与验证: 在或
libs.versions.toml中更新版本后,必须先执行Gradle同步,再进行任何代码重构。这可确保环境已正确解析库依赖。build.gradle.kts - 禁止猜测(错误处理规则): 若同步成功后仍遇到"未解析引用"或API不匹配问题,请勿通过降级库版本来尝试"修复"。
Capabilities and Tools
功能与工具
Capability 1: Migration
功能1:迁移
Use this guidance when migrating from an older version of Wear OS Compose or
Horologist.
- Unless otherwise indicated by the developer, use the latest stable version of Wear Compose Material3 from .
{VERSION} - Read the migration guide
- Use the official component mappings from the migration guide.
- Before refactoring any component (e.g., ->
Chip), check the parameter names, slot types, and "Expressive" design tokens.Button - Do not use the Horologist Composables, Compose Layout, or Compose Material libraries.
- Always check against the component guidance in Capability #3.
- Expect screenshot tests to fail when a migration has been performed: Even when migrating to very similar components, expected defaults for padding and positioning will have changed. Do not seek to artificially match the pre-migration screenshot, but give preference to the Material3 defaults.
当从旧版本Wear OS Compose或Horologist迁移时,请遵循以下指导。
- 除非开发者另有说明,否则使用指定的Wear Compose Material3最新稳定版本。
{VERSION} - 阅读迁移指南
- 使用迁移指南中的官方组件映射关系。
- 在重构任何组件(如->
Chip)之前,检查参数名称、插槽类型和"Expressive"设计标记。Button - 请勿使用Horologist Composables、Compose Layout或Compose Material库。
- 务必对照功能3中的组件使用指南进行检查。
- 迁移完成后,截图测试可能会失败:即使迁移到非常相似的组件,内边距和位置的默认值也可能已更改。请勿刻意匹配迁移前的截图,应优先使用Material3的默认设置。
Capability 2: Component samples
功能2:组件示例
Wear Compose includes individual component samples for each and every component,
within the file. Gradle automatically
downloads these JAR files along with the main library JAR when using any of
, or .
<artifact>-<version>-samples-sources.jarcompose-material3compose-foundationcompose-navigation3Use the canonical component samples whenever adding or adjusting a Wear Compose
Material3 component.
STRICT COMPLIANCE: Extraction is NOT optional. You are FORBIDDEN from
implementing any code until samples are extracted and read. Bypassing this step
with alternative search tools or by assuming library documentation is sufficient
is a protocol breach. You MUST verify the local cache by reading a sample file
before proceeding.
Wear Compose在文件中包含每个组件的独立示例。当使用、或中的任意一个库时,Gradle会自动将这些JAR文件与主库JAR一起下载。
<artifact>-<version>-samples-sources.jarcompose-material3compose-foundationcompose-navigation3添加或调整Wear Compose Material3组件时,请使用官方标准组件示例。
严格合规:提取示例并非可选步骤。在提取并阅读示例之前,禁止编写任何代码。使用其他搜索工具或假设库文档足够而跳过此步骤属于违反规则。继续操作前,必须通过阅读示例文件来验证本地缓存。
Step 1: Prepare
步骤1:准备
- Check the or
build.gradle.ktsto ensure the Wear Compose version matcheslibs.versions.toml.{VERSION} - Ensure that the necessary dependencies are downloaded by doing a Gradle sync.
- 检查或
build.gradle.kts,确保Wear Compose版本与libs.versions.toml一致。{VERSION} - 执行Gradle同步,确保已下载必要的依赖项。
Step 2: Check the Local Cache
步骤2:检查本地缓存
- Define the cache directory path: . Do NOT choose your own different location.
<SKILL_ROOT>/samples/{VERSION}/ - Check if this directory exists and contains subdirectories with files.
.kt- IF YES (Cache Hit): Proceed to Step 4.
- IF NO (Cache Miss): Proceed to Step 3.
- 定义缓存目录路径:。请勿自行选择其他路径。
<SKILL_ROOT>/samples/{VERSION}/ - 检查该目录是否存在且包含带有文件的子目录。
.kt- 如果存在(缓存命中): 继续执行步骤4。
- 如果不存在(缓存未命中): 继续执行步骤3。
Step 3: Check the Gradle Cache
步骤3:检查Gradle缓存
-
Sample sources are stored in the Gradle cache. To avoid slow, brute-force searches:
- Determine the Gradle User Home (usually , or check
~/.gradle).$GRADLE_USER_HOME - The cache root is . Call this
<GRADLE_USER_HOME>/caches.<CACHE_ROOT>
- Determine the Gradle User Home (usually
-
Defineas the items in the list
{ARTIFACT}. Also include "navigation3" in the list if the["material3", "foundation"]library is being used.androidx.wear.compose.navigation3 -
For eachin the list:
{ARTIFACT}-
Construct the expected relative path segment for the library:.
androidx.wear.compose/compose-{ARTIFACT}/{VERSION} -
Run a targetedcommand. Here is an example which is constructed for efficiency:
findfind <CACHE_ROOT>/modules-2/files-2.1/androidx.wear.compose/compose-{ARTIFACT}/{VERSION}/ \ -name "*samples-sources.jar"
-
-
Use this JAR as the official sample sources.
-
Extract the contents of each JAR tousing
<SKILL_ROOT>/samples/{VERSION}/{ARTIFACT}/to flatten the structure.unzip -j -
Proceed directly to step 4.
-
示例源码存储在Gradle缓存中。为避免缓慢的暴力搜索:
- 确定Gradle用户主目录(通常为,或检查
~/.gradle环境变量)。$GRADLE_USER_HOME - 缓存根目录为,记为
<GRADLE_USER_HOME>/caches。<CACHE_ROOT>
- 确定Gradle用户主目录(通常为
-
将定义为列表
{ARTIFACT}中的项。如果使用了["material3", "foundation"]库,还需将"navigation3"加入列表。androidx.wear.compose.navigation3 -
对列表中的每个:
{ARTIFACT}-
构造库的预期相对路径片段:。
androidx.wear.compose/compose-{ARTIFACT}/{VERSION} -
执行针对性的命令。以下是一个高效的示例:
findfind <CACHE_ROOT>/modules-2/files-2.1/androidx.wear.compose/compose-{ARTIFACT}/{VERSION}/
-name "*samples-sources.jar"
-
-
将找到的JAR文件作为官方示例源码。
-
使用命令将每个JAR文件的内容提取到
unzip -j,以扁平化目录结构。<SKILL_ROOT>/samples/{VERSION}/{ARTIFACT}/ -
直接进入步骤4。
Step 4: Read Samples and Implement
步骤4:阅读示例并实现
- Read the relevant sample files.
.kt - Use these official, version-matched samples as the for:
- Required parameters and slot names.
- Default styling and typography tokens.
- Interactive behaviors (e.g., ,
onClick).onLongClick - Component nesting (e.g., ->
AppScaffold).ScreenScaffold
- 阅读相关的示例文件。
.kt - 将这些官方、版本匹配的示例作为参考,用于:
- 必填参数和插槽名称。
- 默认样式和排版标记。
- 交互行为(如、
onClick)。onLongClick - 组件嵌套(如->
AppScaffold)。ScreenScaffold
Capability 3: Component guidance
功能3:组件使用指南
Mandatory: Use this capability as a checklist against any component use. It
provides more holistic guidance on how to use each component in practice, beyond
the component syntax.
-
and
AppScaffoldScreenScaffold- [ ] Use as the outer container, with
AppScaffoldchildren.ScreenScaffold - [ ] Use only ONE and any number of
AppScaffold.ScreenScaffold
- [ ] Use
-
- Use
ScalingLazyColumninstead.TransformingLazyColumn -
TransformingLazyColumnYou will need the following imports:<br />kotlinimport androidx.wear.compose.foundation.lazy.TransformingLazyColumn import androidx.wear.compose.foundation.lazy.TransformingLazyColumnDefaults import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState // ... import androidx.wear.compose.material3.lazy.rememberTransformationSpec import androidx.wear.compose.material3.lazy.transformedHeightCanonical example:<br />kotlinval columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }- [ ] Use instead of
TransformingLazyColumnScalingLazyColumn - [ ] You must pass the parameter from
contentPaddingto theScreenScaffold.TransformingLazyColumn - [ ] Use the modifier to achieve required padding top and bottom.
minimumVerticalContentPadding- This expects a value from defaults, such as ,
ButtonDefaults, `ListHeaderDefaults.CardDefaults - Note: This is a scoped modifier available within .
TransformingLazyColumnItemScope
- This expects a value from defaults, such as
- [ ] Ensure the list morphs and scales.
- [ ] Use modifier.
transformedHeight - [ ] Use .
transform = SurfaceTransform(...) - [ ] If configuring a list for snapping, use and
flingBehaviortogether:rotaryScrollableBehavior
<br />kotlinval columnState = rememberTransformingLazyColumnState() ScreenScaffold(scrollState = columnState) { contentPadding -> TransformingLazyColumn( state = columnState, flingBehavior = TransformingLazyColumnDefaults.snapFlingBehavior(columnState), rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior(columnState) ) { // ... // ... } } - [ ] Use
-
ScreenScaffold- [ ] Guard the with
scrollIndicator!LocalScrollCaptureInProgress.current
- [ ] Guard the
-
EdgeButton- [ ] Do NOT use as the final item within a . Instead, use the slot in
TransformingLazyColumn.ScreenScaffold - [ ] When used in a , add the required overscroll behavior:
TransformingLazyColumn
<br />kotlinval columnState = rememberTransformingLazyColumnState() ScreenScaffold( scrollState = columnState, edgeButton = { EdgeButton( onClick = { /* TODO */ }, modifier = Modifier.scrollable( columnState, orientation = Orientation.Vertical, reverseDirection = true, // Apply overscroll to the EdgeButton for proper scrolling behavior. overscrollEffect = rememberOverscrollEffect(), ) ) { Text("More") } } ) { contentPadding -> TransformingLazyColumn( contentPadding = contentPadding, state = columnState, ) { // ... // ... } } - [ ] Do NOT use as the final item within a
-
Column- [ ] USE as a direct child of if the screen is will never scroll, even with the largest system font.
ScreenScaffold - [ ] Use instead for all other cases.
TransformingLazyColumn
- [ ] USE as a direct child of
-
Styles
- [ ] Do NOT hard-code text sizes, use from
typography.MaterialTheme - [ ] Do NOT hard-code colors, use from
colorScheme.MaterialTheme
- [ ] Do NOT hard-code text sizes, use
-
Use component defaults
- [ ] Components such as have a corresponding
Buttonobject.ButtonDefaults - Check for and use the object for any component when working with padding and styling values, in preference to hard-coded values.
*Defaults
- [ ] Components such as
-
Use Wear specific previews
- [ ]
WearPreviewDevices - [ ]
WearPreviewFontScales
- [ ]
-
Ambient mode
- [ ] Use instead of
LocalAmbientModeManager.AmbientLifecycleObserver
- [ ] Use
-
Navigation
- [ ] When adding navigation fresh, use Navigation3.
- [ ] For Navigation3 in Wear OS, use from the Wear Compose
SwipeDismissableSceneStrategy()library.compose-navigation3
强制要求:将此功能作为组件使用的检查清单。它提供了超越组件语法的、更全面的实际使用指导。
-
和
AppScaffoldScreenScaffold- 使用作为外层容器,
AppScaffold作为其子组件。ScreenScaffold - 只能使用一个,可使用任意数量的
AppScaffold。ScreenScaffold
- 使用
-
- 请改用
ScalingLazyColumn。TransformingLazyColumn -
TransformingLazyColumn你需要导入以下内容:<br />kotlinimport androidx.wear.compose.foundation.lazy.TransformingLazyColumn import androidx.wear.compose.foundation.lazy.TransformingLazyColumnDefaults import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState // ... import androidx.wear.compose.material3.lazy.rememberTransformationSpec import androidx.wear.compose.material3.lazy.transformedHeight标准示例:<br />kotlinval columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }- 使用替代
TransformingLazyColumnScalingLazyColumn - 必须将的
ScreenScaffold参数传递给contentPadding。TransformingLazyColumn - 使用修饰符来设置所需的上下内边距。
minimumVerticalContentPadding- 该值应取自默认配置对象,如、
ButtonDefaults、CardDefaults。ListHeaderDefaults - 注意:这是内可用的作用域修饰符。
TransformingLazyColumnItemScope
- 该值应取自默认配置对象,如
- 确保列表可变形和缩放。
- 使用修饰符。
transformedHeight - 使用。
transform = SurfaceTransform(...) - 如果配置列表为可吸附(snapping)模式,需同时使用和
flingBehavior:rotaryScrollableBehavior
<br />kotlinval columnState = rememberTransformingLazyColumnState() ScreenScaffold(scrollState = columnState) { contentPadding -> TransformingLazyColumn( state = columnState, flingBehavior = TransformingLazyColumnDefaults.snapFlingBehavior(columnState), rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior(columnState) ) { // ... // ... } } - 使用
-
ScreenScaffold- 使用来保护
!LocalScrollCaptureInProgress.currentscrollIndicator
- 使用
-
EdgeButton- 请勿将其用作的最后一项。应改用
TransformingLazyColumn中的插槽。ScreenScaffold - 若在中使用,需添加所需的过度滚动行为:
TransformingLazyColumn
<br />kotlinval columnState = rememberTransformingLazyColumnState() ScreenScaffold( scrollState = columnState, edgeButton = { EdgeButton( onClick = { /* TODO */ }, modifier = Modifier.scrollable( columnState, orientation = Orientation.Vertical, reverseDirection = true, // Apply overscroll to the EdgeButton for proper scrolling behavior. overscrollEffect = rememberOverscrollEffect(), ) ) { Text("More") } } ) { contentPadding -> TransformingLazyColumn( contentPadding = contentPadding, state = columnState, ) { // ... // ... } } - 请勿将其用作
-
Column- 只有当屏幕永远不会滚动(即使使用最大系统字体)时,才将其用作的直接子组件。
ScreenScaffold - 其他所有情况请改用。
TransformingLazyColumn
- 只有当屏幕永远不会滚动(即使使用最大系统字体)时,才将其用作
-
样式
- 请勿硬编码文本大小,请使用中的
MaterialTheme。typography - 请勿硬编码颜色,请使用中的
MaterialTheme。colorScheme
- 请勿硬编码文本大小,请使用
-
使用组件默认配置
- 诸如之类的组件有对应的
Button对象。ButtonDefaults - 处理内边距和样式值时,请查找并使用各组件的对象,优先于硬编码值。
*Defaults
- 诸如
-
使用Wear专用预览
-
WearPreviewDevices -
WearPreviewFontScales
-
-
环境模式
- 使用替代
LocalAmbientModeManager。AmbientLifecycleObserver
- 使用
-
导航
- 新增导航功能时,请使用Navigation3。
- 对于Wear OS中的Navigation3,请使用Wear Compose 库中的
compose-navigation3。SwipeDismissableSceneStrategy()