레이아웃에는 백분율 기반 여백이 있어야 합니다. Compose는 기본적으로 절대값으로 작동하므로 Horologist 라이브러리의 rememberResponsiveColumnPadding를 사용하여 패딩을 계산하고 이를 ScreenScaffold의 contentPadding 매개변수와 TransformingLazyColumn의 contentPadding 매개변수에 전달합니다.
다음 코드 스니펫은 TransformingLazyColumn 구성요소를 사용하여 다양한 Wear OS 화면 크기에서 보기 좋은 콘텐츠를 만듭니다.
valcolumnState=rememberTransformingLazyColumnState()valcontentPadding=rememberResponsiveColumnPadding(first=ColumnItemType.ListHeader,last=ColumnItemType.Button,)valtransformationSpec=rememberTransformationSpec()ScreenScaffold(scrollState=columnState,contentPadding=contentPadding){contentPadding->
TransformingLazyColumn(state=columnState,contentPadding=contentPadding){item{ListHeader(modifier=Modifier.fillMaxWidth().transformedHeight(this,transformationSpec),transformation=SurfaceTransformation(transformationSpec)){Text(text="Header")}}// ... other itemsitem{Button(modifier=Modifier.fillMaxWidth().transformedHeight(this,transformationSpec),transformation=SurfaceTransformation(transformationSpec),onClick={/* ... */},icon={Icon(imageVector=Icons.Default.Build,contentDescription="build",)},){Text(text="Build",maxLines=1,overflow=TextOverflow.Ellipsis,)}}}}
JetCaster 샘플: Horologist 라이브러리를 사용하여 다양한 화면 크기에서 작동하는 앱을 빌드하는 더 복잡한 예시입니다.
앱에서 스크롤 레이아웃 사용
화면을 구현할 때 이 페이지의 앞부분에 나온 스크롤 레이아웃을 기본 선택사항으로 사용합니다. 이를 통해 사용자는 디스플레이 환경설정이나 Wear OS 기기 화면 크기와 관계없이 앱의 구성요소에 도달할 수 있습니다.
다양한 기기 크기와 글꼴 크기 조정의 효과
대화상자
매우 타당한 이유가 없는 한 대화상자는 스크롤 가능해야 합니다.
AlertDialog 구성요소는 반응형이며 콘텐츠가 표시 영역 높이를 초과하는 경우 기본적으로 스크롤할 수 있습니다.
맞춤 화면에는 스크롤하지 않는 레이아웃이 필요할 수 있음
일부 화면은 스크롤하지 않는 레이아웃에 적합할 수 있습니다. 미디어 앱의 기본 플레이어 화면과 피트니스 앱의 운동 화면이 그 예입니다.
이러한 경우 Figma 디자인 키트에 제공된 표준 안내를 살펴보고 올바른 여백을 사용하여 화면 크기에 반응하는 디자인을 구현하세요.
중단점을 통해 차별화된 환경 제공
더 큰 디스플레이를 사용하면 추가 콘텐츠와 기능을 도입할 수 있습니다. 이러한 차별화된 환경을 구현하려면 화면 크기 중단점을 사용하여 화면 크기가 225dp를 초과할 때 다른 레이아웃을 표시하세요.
constvalLARGE_DISPLAY_BREAKPOINT=225@ComposablefunisLargeDisplay()=LocalConfiguration.current.screenWidthDp>=LARGE_DISPLAY_BREAKPOINT// ...// ... use in your Composables:if(isLargeDisplay()){// Show additional content.}else{// Show content only for smaller displays.}// ...
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-09-02(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-02(UTC)"],[],[],null,["Compose for Wear OS Material version 2.5 3\n\n*** ** * ** ***\n\nYour app should work well on Wear OS devices of all sizes, taking advantage of\nadditional space where available, and still look great on smaller screens too.\nThis guide provides recommendations for achieving this user experience.\n\nTo learn more about the design principles for adaptive layouts, read the\n[design guidance](/design/ui/wear/guides/foundations/adaptive-layouts).\n\n\nBuild responsive layouts using Material 3 Layouts should have [percentage-based margins](/design/ui/wear/guides/foundations/canonical-adaptive-layouts#non-scrolling-responsiveness). Because Compose works by default in absolute values instead, use `rememberResponsiveColumnPadding` from the [Horologist Library](https://github.com/google/horologist) to calculate the padding and pass it to the `ScreenScaffold`'s `contentPadding` parameter and the `TransformingLazyColumn`'s `contentPadding` parameter.\n\n\u003cbr /\u003e\n\nThe following code snippet uses a\n`TransformingLazyColumn` component to create content that looks great on a variety\nof Wear OS screen sizes: \n\n```kotlin\nval columnState = rememberTransformingLazyColumnState()\nval contentPadding = rememberResponsiveColumnPadding(\n first = ColumnItemType.ListHeader,\n last = ColumnItemType.Button,\n)\nval transformationSpec = rememberTransformationSpec()\nScreenScaffold(\n scrollState = columnState,\n contentPadding = contentPadding\n) { contentPadding -\u003e\n TransformingLazyColumn(\n state = columnState,\n contentPadding = contentPadding\n ) {\n item {\n ListHeader(\n modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),\n transformation = SurfaceTransformation(transformationSpec)\n ) {\n Text(text = \"Header\")\n }\n }\n // ... other items\n item {\n Button(\n modifier = Modifier.fillMaxWidth().transformedHeight(this, transformationSpec),\n transformation = SurfaceTransformation(transformationSpec),\n onClick = { /* ... */ },\n icon = {\n Icon(\n imageVector = Icons.Default.Build,\n contentDescription = \"build\",\n )\n },\n ) {\n Text(\n text = \"Build\",\n maxLines = 1,\n overflow = TextOverflow.Ellipsis,\n )\n }\n }\n }\n}https://github.com/android/snippets/blob/e4396f6dd13aaa8099c4baa671cdd549a10f201c/wear/src/main/java/com/example/wear/snippets/m3/list/List.kt#L53-L96\n```\n\nThis example also demonstrates `ScreenScaffold` and `AppScaffold`.\nThese coordinate between the App and individual screens\n([navigation routes](/training/wearables/compose/navigation)) to ensure the correct scrolling behavior and\n`TimeText` positioning.\n\nFor the top and bottom padding, also note the following:\n\n- The specification of the first and last `ItemType`, to determine the correct padding.\n- The use of `ListHeader` for the first item in the list, because `Text` headers shouldn't have padding.\n\nFull specifications can be found in the [Figma design kits](/design/ui/wear/guides/foundations/download). For more\ndetails and examples, see:\n\n- The [Horologist library](https://github.com/google/horologist) - provides helpers to help build optimized and differentiated apps for Wear OS.\n- The [ComposeStarter sample](https://github.com/android/wear-os-samples/tree/m3/ComposeStarter) - an example showing the principles outlined in this guide.\n- The [JetCaster sample](https://github.com/android/compose-samples/tree/main/Jetcaster) - a more complex example of building an app to work with different screen sizes, using the Horologist library.\n\nUse scrolling layouts in your app\n\nUse a scrolling layout, as shown earlier on this page, as the default choice\nwhen implementing your screens. This lets users reach your app's components\nregardless of display preferences or Wear OS device screen size. \n\n*The effect of different device sizes\nand font-scaling.*\n\nDialogs\n\nDialogs should also be scrollable, unless there is a very good reason not to.\n\nThe [`AlertDialog`](/reference/kotlin/androidx/wear/compose/material3/package-summary?#AlertDialog(kotlin.Boolean,kotlin.Function0,kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Function0,kotlin.Function0,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.PaddingValues,androidx.compose.ui.window.DialogProperties,kotlin.Function1)) component is responsive and is scrollable by default\nif the content exceeds the viewport height.\n\n\nCustom screens might require non-scrolling layouts\n\nSome screens may still be suited to non-scrolling layouts. Several examples\ninclude the main player screen in a media app and the workout screen in a\nfitness app.\n\nIn these cases, look at the canonical guidance provided in the\n[Figma design kits](/design/ui/wear/guides/foundations/download), and implement a design that is responsive to the size\nof the screen, using the correct margins.\n\nProvide differentiated experiences through breakpoints\n\nWith larger displays, you can introduce additional content and features. To\nimplement this sort of differentiated experience, use *screen size breakpoints*,\nshowing a different layout when the screen size exceeds 225 dp: \n\n```kotlin\nconst val LARGE_DISPLAY_BREAKPOINT = 225\n\n@Composable\nfun isLargeDisplay() =\n LocalConfiguration.current.screenWidthDp \u003e= LARGE_DISPLAY_BREAKPOINT\n\n// ...\n// ... use in your Composables:\n if (isLargeDisplay()) {\n // Show additional content.\n } else {\n // Show content only for smaller displays.\n }\n // ... \nhttps://github.com/android/snippets/blob/e4396f6dd13aaa8099c4baa671cdd549a10f201c/wear/src/main/java/com/example/wear/snippets/m3/list/List.kt#L140-L158\n```\n\nThe [design guidance](/design/ui/wear/guides/foundations/larger-screens-differentiated) illustrates more of these opportunities.\n\nTest combinations of screen and font sizes using previews\n\n[Compose previews](/develop/ui/compose/tooling/previews) help you develop for a variety of Wear OS screen sizes.\nUse both the devices and font-scaling preview definitions to see the following:\n\n- How your screens look at the extremes of sizing, for example, largest font paired with smallest screen.\n- How your differentiated experience behaves across breakpoints.\n\nEnsure you implement previews using [`WearPreviewDevices`](/reference/kotlin/androidx/wear/compose/ui/tooling/preview/WearPreviewDevices) and\n[`WearPreviewFontScales`](/reference/kotlin/androidx/wear/compose/ui/tooling/preview/WearPreviewFontScales) for all the screens in your app. \n\n```kotlin\n@WearPreviewDevices\n@WearPreviewFontScales\n@Composable\nfun ComposeListPreview() {\n ComposeList()\n}https://github.com/android/snippets/blob/e4396f6dd13aaa8099c4baa671cdd549a10f201c/wear/src/main/java/com/example/wear/snippets/m3/list/List.kt#L162-L167\n```\n\nScreenshot testing\n\nBeyond preview testing, screenshot testing lets you test against a range of\nexisting hardware sizes. This is particularly useful where those devices might\nnot be immediately available to you, and the issue may not present itself on\nother screen sizes.\n\nScreenshot testing also helps you identify regressions at specific locations in\nyour codebase.\n\nOur samples use [Roborazzi](https://github.com/takahirom/roborazzi) for screenshot testing:\n\n1. Configure your [project](https://github.com/android/wear-os-samples/blob/main/ComposeStarter/build.gradle.kts) and [app](https://github.com/android/wear-os-samples/blob/main/ComposeStarter/app/build.gradle.kts) `build.gradle` files to use Roborazzi.\n2. Create a screenshot test for each screen you have in your app. For example, in the ComposeStarter sample, a test for the [`GreetingScreen`](https://github.com/android/wear-os-samples/blob/main/ComposeStarter/app/src/main/java/com/example/android/wearable/composestarter/presentation/MainActivity.kt#L109) is implemented as seen in [`GreetingScreenTest`](https://github.com/android/wear-os-samples/blob/main/ComposeStarter/app/src/test/java/presentation/GreetingScreenTest.kt):\n\n @RunWith(ParameterizedRobolectricTestRunner::class)\n class GreetingScreenTest(override val device: WearDevice) : WearScreenshotTest() {\n override val tolerance = 0.02f\n\n @Test\n fun greetingScreenTest() = runTest {\n AppScaffold {\n GreetingScreen(greetingName = \"screenshot\", onShowList = {})\n }\n }\n\n companion object {\n @JvmStatic\n @ParameterizedRobolectricTestRunner.Parameters\n fun devices() = WearDevice.entries\n }\n }\n\nSome important points to note:\n\n- `WearDevice.entries` contains definitions for most popular Wear OS devices so that the tests are run on a representative range of screen sizes.\n\nGenerate golden images\n\nTo generate images for your screens, run the following command in a terminal: \n\n ./gradlew recordRoborazziDebug\n\nVerify images\n\nTo verify changes against existing images, run the following command in a\nterminal: \n\n ./gradlew verifyRoborazziDebug\n\nFor a full example of screenshot testing, see the [ComposeStarter](https://github.com/android/wear-os-samples/tree/main/ComposeStarter) sample."]]