Android 15 이상을 실행하는 기기에서 SDK 35 이상을 타겟팅하면 앱이 더 넓은 화면에 표시됩니다. 이 창은 시스템 표시줄 뒤에 그려져 디스플레이의 전체 너비와 높이에 걸쳐 표시됩니다. 시스템 표시줄에는 상태 표시줄, 자막 메뉴, 탐색 메뉴가 있습니다.
많은 앱에는 상단 앱 바가 있습니다. 상단 앱 바가 화면의 상단 가장자리까지 확장되고 상태 표시줄 뒤에 표시되어야 합니다. 원하는 경우 상단 앱 바는 콘텐츠를 스크롤할 때 상태 표시줄 높이로 축소될 수 있습니다.
또한 많은 앱에는 하단 앱 바 또는 하단 탐색 메뉴가 있습니다. 또한 이러한 표시줄은 화면 하단 가장자리까지 확장되어야 하며 탐색 메뉴 뒤에 표시되어야 합니다. 그러지 않으면 앱에서 탐색 메뉴 뒤에 스크롤 콘텐츠를 표시해야 합니다.
앱에서 더 넓은 화면 레이아웃을 구현할 때는 다음 사항에 유의하세요.
- 더 넓은 화면 디스플레이 사용 설정
- 시각적으로 겹치는 부분을 처리합니다.
- 시스템 표시줄 뒤에 스크림을 표시하는 것이 좋습니다.
![상태 표시줄 뒤에 있는 이미지의 예](https://developer.android.google.cn/static/images/guide/navigation/e2e-imagery-behind-status-bar.png?authuser=7&hl=ko)
더 넓은 화면 디스플레이 사용 설정
앱에서 SDK 35 이상을 타겟팅하면 Android 15 이상 기기에서는 더 넓은 화면이 자동으로 사용 설정됩니다.
이전 Android 버전에서 더 넓은 화면을 사용 설정하려면 다음 단계를 따르세요.
앱 또는 모듈의
build.gradle
파일에 있는androidx.activity
라이브러리에 종속 항목을 추가합니다.Kotlin
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Groovy
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }enableEdgeToEdge
확장 함수를 앱으로 가져옵니다.
Activity
의 onCreate
에서 enableEdgeToEdge
를 호출하여 수동으로 더 넓은 화면을 사용 설정합니다. setContentView
전에 호출해야 합니다.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
기본적으로 enableEdgeToEdge()
는 시스템 표시줄을 투명하게 만듭니다. 단, 상태 표시줄에 반투명한 스크림이 적용되는 3버튼 탐색 모드는 예외입니다. 시스템 아이콘과 스크림의 색상은 시스템의 밝은 테마나 어두운 테마에 따라 조정됩니다.
enableEdgeToEdge()
함수는 앱을 더 넓은 화면에 배치하도록 자동으로 선언하고 시스템 표시줄의 색상을 조정합니다.
enableEdgeToEdge()
함수를 사용하지 않고 앱에서 더 넓은 화면 디스플레이를 사용 설정하려면 수동으로 더 넓은 화면 설정을 참고하세요.
인셋을 사용하여 중복 처리
그림 3과 같이 앱의 뷰 중 일부가 시스템 표시줄 뒤에 그려질 수 있습니다.
탐색 메뉴 또는 상태 표시줄과 같은 시스템 UI와 교차하는 화면을 지정하는 인셋에 반응하여 중첩을 해결할 수 있습니다. 교차는 콘텐츠 위에 표시하는 것을 의미할 수 있지만 시스템 동작을 앱에 알릴 수도 있습니다.
앱을 더 넓은 화면으로 표시하는 데 적용되는 인셋 유형은 다음과 같습니다.
시스템 표시줄 인셋: 탭할 수 있고 시스템 표시줄로 인해 시각적으로 가려지지 않아야 하는 뷰에 가장 적합합니다.
디스플레이 컷아웃 인셋: 기기의 모양으로 인해 화면 컷아웃이 있을 수 있는 영역에 사용됩니다.
시스템 동작 인셋: 시스템에서 사용하는 동작 탐색 영역으로, 앱보다 우선순위가 높습니다.
시스템 표시줄 인셋
시스템 표시줄 삽입은 가장 일반적으로 사용되는 삽입 유형입니다. 이는 시스템 UI가 앱 위의 Z축에 표시되는 영역을 나타냅니다. 앱에서 탭할 수 있고 시스템 표시줄로 인해 시각적으로 가려지면 안 되는 앱의 뷰를 이동하거나 패딩하는 데 가장 적합합니다.
예를 들어, 그림 3의 플로팅 작업 버튼 (FAB)은 탐색 메뉴로 인해 부분적으로 가려집니다.
![더 넓은 화면 구현 예, 탐색 메뉴가 FAB를 가림](https://developer.android.google.cn/static/images/guide/navigation/e2e-after-implementation.png?authuser=7&hl=ko)
동작 모드나 버튼 모드에서 이러한 종류의 시각적 중첩을 방지하려면 WindowInsetsCompat.Type.systemBars()
와 함께 getInsets(int)
를 사용하여 뷰의 여백을 늘리면 됩니다.
다음 코드 예는 시스템 표시줄 인셋을 구현하는 방법을 보여줍니다.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left, bottomMargin = insets.bottom, rightMargin = insets.right, } // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
이 솔루션을 그림 3의 예에 적용하면 그림 4와 같이 버튼 모드에서 시각적으로 겹치지 않습니다.
![FAB를 가리지 않는 반투명 탐색 메뉴가](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-bars-top.png?authuser=7&hl=ko)
그림 5와 같이 동작 탐색 모드에도 동일하게 적용됩니다.
![동작 탐색이 있는 더 넓은 화면](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-bars-bottom.png?authuser=7&hl=ko)
디스플레이 컷아웃 인셋
일부 기기에는 디스플레이 컷아웃이 있습니다. 일반적으로 컷아웃은 화면 상단에 있으며 상태 표시줄에 포함됩니다. 기기 화면이 가로 모드일 때는 컷아웃이 세로 가장자리에 있을 수 있습니다. 앱에서 화면에 표시하는 콘텐츠에 따라 디스플레이 컷아웃을 방지하기 위해 패딩을 구현해야 합니다. 기본적으로 앱은 디스플레이 컷아웃에 그려지기 때문입니다.
예를 들어 대다수의 앱 화면에는 항목 목록이 표시됩니다. 디스플레이 컷아웃이나 시스템 표시줄로 목록 항목을 가리지 마세요.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { WindowInsetsCompat bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
시스템 표시줄과 디스플레이 컷아웃 유형의 논리 or를 취해 WindowInsetsCompat
값을 결정합니다.
패딩이 목록 항목과 함께 스크롤되도록 clipToPadding
를 RecyclerView
로 설정합니다. 이렇게 하면 다음 예와 같이 사용자가 스크롤할 때 항목이 시스템 표시줄 뒤로 이동할 수 있습니다.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
시스템 동작 인셋
시스템 동작 인셋은 시스템 동작이 앱보다 우선하는 창 영역을 나타냅니다. 이러한 영역은 그림 6에 주황색으로 표시되어 있습니다.
![시스템 동작 삽입의 예](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-gesture-insets.png?authuser=7&hl=ko)
시스템 표시줄 인셋과 마찬가지로 getInsets(int)
를 WindowInsetsCompat.Type.systemGestures()
와 함께 사용하면 시스템 동작 인셋이 겹치지 않도록 할 수 있습니다.
이 인셋을 사용하여 스와이프할 수 있는 뷰를 가장자리에서 멀리 이동하거나 패딩합니다. 일반적인 사용 사례로는 하단 시트, 게임에서 스와이프, ViewPager2
를 사용하여 구현된 캐러셀이 있습니다.
Android 10 이상에서는 시스템 동작 인셋에 홈 동작을 위한 하단 인셋과 뒤로 동작을 위한 왼쪽 및 오른쪽 인셋이 포함됩니다.
![시스템 동작 인셋 측정의 예](https://developer.android.google.cn/static/images/guide/navigation/e2e-system-gesture-insets-measurements.png?authuser=7&hl=ko)
다음 코드 예는 시스템 동작 삽입을 구현하는 방법을 보여줍니다.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
몰입형 모드
일부 콘텐츠는 전체 화면에서 가장 잘 표시되어 사용자에게 더 몰입감 있는 환경을 제공합니다. WindowInsetsController
및 WindowInsetsControllerCompat
라이브러리를 사용하여 몰입형 모드의 시스템 표시줄을 숨길 수 있습니다.
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
이 기능 구현에 관한 자세한 내용은 몰입형 모드의 시스템 표시줄 숨기기를 참고하세요.
추가 리소스
WindowInsets
, 동작 탐색, 인셋 작동 방식에 관한 자세한 내용은 다음 참조를 확인하세요.