디스플레이 컷아웃 지원

디스플레이 컷아웃이 있는 기기

디스플레이 컷아웃은 일부 기기에서 디스플레이 표면으로 확장되는 영역으로, 기기 전면에 중요한 센서를 위한 공간을 제공하는 동시에 에지 투 에지 경험을 가능하게 합니다. Android는 Android 9(API 레벨 28) 이상을 실행하는 기기에서 공식적으로 디스플레이 컷아웃을 지원합니다. 기기 제조업체는 Android 8.1 이하를 실행하는 기기에서도 디스플레이 컷아웃을 지원할 수 있습니다.

이 주제에서는 컷아웃 영역(컷아웃이 포함된 디스플레이 표면의 에지 투 에지 사각형)을 사용하는 방법을 포함하여 컷아웃이 있는 기기를 위한 지원을 구현하는 방법을 설명합니다.

디스플레이 컷아웃이 있는 기기에서 예상되는 사항

Android 9을 실행하는 기기는 일관성과 앱 호환성을 보장하기 위해 다음과 같은 컷아웃 동작을 보장해야 합니다.

  • 단일 가장자리에 컷아웃을 최대 1개 포함할 수 있습니다.
  • 기기에 컷아웃이 3개 이상 있을 수 없습니다.
  • 기기 양쪽의 긴 가장자리에는 컷아웃이 있을 수 없습니다.
  • 특수 플래그를 설정하지 않은 세로 방향에서는 상태 표시줄이 적어도 컷아웃 높이까지 확장되어야 합니다.
  • 기본적으로 전체 화면 또는 가로 방향에서는 전체 컷아웃 영역이 레터박스 처리되어야 합니다.

앱의 컷아웃 영역 처리 방법 선택하기

콘텐츠가 컷아웃 영역과 겹치지 않게 하려면 콘텐츠가 상태 표시줄 및 탐색 메뉴와 겹치지 않게 만들면 대체로 충분합니다. 컷아웃 영역으로 렌더링하는 경우 WindowInsets.getDisplayCutout()을 사용하여 각 컷아웃의 안전 인셋 및 경계 상자가 포함된 DisplayCutout 객체를 검색할 수 있습니다. 이러한 API를 사용하면 콘텐츠가 컷아웃과 겹치는지 여부를 확인하여 필요한 경우 위치를 변경할 수 있습니다.

Android에서는 또한 컷아웃 영역 내에 콘텐츠를 표시할지 여부를 제어할 수 있습니다. 창 레이아웃 속성 layoutInDisplayCutoutMode는 컷아웃 영역에 콘텐츠가 그려지는 방식을 제어합니다. layoutInDisplayCutoutMode를 다음 값 중 하나로 설정할 수 있습니다.

컷아웃 모드는 프로그래밍 방식으로 설정하거나 활동에 스타일을 지정하여 설정할 수 있습니다. 아래 예에서는 활동에 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 속성을 적용하는 데 사용할 수 있는 스타일을 정의합니다.

    <style name="ActivityTheme">
      <item name="android:windowLayoutInDisplayCutoutMode">
        shortEdges <!-- default, shortEdges, never -->
      </item>
    </style>
    

아래 섹션에서는 다양한 컷아웃 모드를 자세히 설명합니다.

기본 동작

기본적으로 특수 플래그가 설정되지 않은 세로 모드에서는 컷아웃이 있는 기기의 상태 표시줄 크기가 최소 컷아웃 높이까지 조절되어 아래 영역에 콘텐츠가 표시됩니다. 가로 모드나 전체 화면 모드에서는 컷아웃 영역에 콘텐츠가 표시되지 않도록 앱 창이 레터박스 처리됩니다.

짧은 가장자리 컷아웃 영역에서 콘텐츠 렌더링하기

동영상, 사진, 지도, 게임과 같은 일부 콘텐츠의 경우 컷아웃 영역으로 렌더링하면 사용자에게 더 몰입도 높은 에지 투 에지 경험을 효과적으로 제공할 수 있습니다. LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES를 사용하면 시스템 표시줄이 숨겨지거나 표시되는지에 관계없이 세로 모드와 가로 모드에서 모두 콘텐츠가 디스플레이의 짧은 가장자리에 있는 컷아웃 영역으로 확장됩니다. 창은 화면의 긴 가장자리에 있는 컷아웃 영역으로 확장될 수 없습니다. 이 모드를 사용할 때는 중요한 콘텐츠가 컷아웃 영역과 겹치지 않도록 해야 합니다.

Android에서는 콘텐츠 뷰가 시스템 표시줄과 겹치는 것을 허용하지 않을 수 있습니다. 이 동작을 재정의하고 콘텐츠를 컷아웃 영역으로 확장하려면 View.setSystemUiVisibility(int) 메서드를 통해 뷰 가시성에 다음 플래그 중 하나를 적용합니다.

  • SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
  • SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
  • SYSTEM_UI_FLAG_LAYOUT_STABLE

다음은 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES의 예입니다.

세로 모드에서 컷아웃 영역으로 콘텐츠 렌더링

가로 모드에서 컷아웃 영역으로 콘텐츠 렌더링

모서리의 컷아웃은 짧은 가장자리에 있는 것으로 간주되므로 동일한 동작이 적용됩니다.

모서리 컷아웃이 있는 기기

디스플레이 컷아웃 영역으로 콘텐츠를 렌더링하지 않음

LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER를 사용하면 창이 컷아웃 영역과 겹쳐질 수 없습니다.

이 모드는 플래그를 설정하거나 해제할 때 창의 다른 레이아웃이 실행되지 않도록 일시적으로 View.SYSTEM_UI_FLAG_FULLSCREEN 또는 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION을 설정하는 창과 함께 사용해야 합니다.

아래에서 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER의 예를 참고하세요.

특수 모드

Android 8.1(API 레벨 27) 이하를 실행하는 일부 기기는 사용자가 레터박스 전체 화면 또는 가로 앱을 컷아웃 영역으로 확장할 수 있는 특수 모드를 지원합니다. 이 모드는 일반적으로 화면을 확장하기 전에 확인을 요구하는 대화상자를 표시하는 탐색 메뉴의 전환 기능을 통해 제어됩니다.

디스플레이 컷아웃 지원 권장사항

디스플레이 컷아웃을 작업할 때는 다음 사항을 고려해야 합니다.

  • 컷아웃 영역이 중요한 텍스트, 컨트롤, 기타 정보를 가리지 않도록 합니다.
  • 미세한 터치 인식을 요구하는 상호작용 요소를 컷아웃 영역에 배치하거나 컷아웃 영역으로 확장하지 않습니다. 터치 민감도는 컷아웃 영역이 더 낮을 수 있습니다.
  • 콘텐츠를 겹치거나 잘라낼 수 있으므로 상태 표시줄 높이를 하드 코딩하지 않습니다. 가능한 경우 WindowInsetsCompat을 사용하여 상태 표시줄 높이를 검색하고 콘텐츠에 적용할 적절한 패딩을 결정합니다.

  • 앱에 전체 창이 있다고 가정하지 않습니다. 대신 View.getLocationInWindow()를 사용하여 창 위치를 확인합니다. View.getLocationOnScreen()을 사용하지 마세요.

  • 전체 화면 모드로 전환 및 전체 화면 모드에서 전환을 제대로 처리해야 합니다. Android 개발자 블로그 게시물을 참고하세요.

  • 세로 모드의 기본 컷아웃 동작의 경우 컷아웃 영역이 상단 가장자리에 있고 창에서 FLAG_FULLSCREEN 또는 View.SYSTEM_UI_FLAG_FULLSCREEN을 설정하지 않았다면 창은 컷아웃 영역으로 확장될 수 있습니다. 마찬가지로 컷아웃 영역이 하단 가장자리에 있고 창에서 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION을 설정하지 않았다면 창은 컷아웃 영역으로 확장될 수 있습니다. 전체 화면 또는 가로 모드에서는 창이 컷아웃 영역과 겹치지 않도록 배치됩니다.

  • 앱이 전체 화면 모드로 전환하거나 전체 화면 모드에서 전환해야 하는 경우 shortEdges 또는 never 컷아웃 모드를 사용합니다. 기본 컷아웃 동작은 전환 중에 아래 이미지처럼 앱의 콘텐츠를 위아래로 이동시킬 수 있습니다.

  • 앱은 레터박스 처리되었을 때 화면 전체를 차지하지 않으므로 전체 화면 모드에서는 창 좌표와 화면 좌표를 사용할 때 주의해야 합니다. 레터박스 때문에 화면 원점 기준의 좌표는 더 이상 창 원점 기준의 좌표와 동일하지 않습니다. 필요에 따라 getLocationOnScreen()을 사용하여 화면 좌표를 뷰의 좌표로 변환할 수 있습니다. 아래 이미지는 콘텐츠가 레터박스 처리되었을 때 좌표가 어떻게 다른지 보여줍니다.

    MotionEvent를 처리할 때는 MotionEvent.getX()MotionEvent.getY()를 사용하여 비슷한 좌표 문제를 방지하세요. MotionEvent.getRawX() 또는 MotionEvent.getRawY()를 사용하지 마세요.

콘텐츠 렌더링 방식 테스트하기

에뮬레이터에서 디스플레이 컷아웃 시뮬레이션하기

앱의 모든 화면과 경험을 테스트해야 합니다. 가능하다면 다양한 유형의 컷아웃이 있는 기기에서 테스트합니다. 컷아웃이 있는 기기가 없는 경우 Android 9을 실행하는 모든 기기 또는 에뮬레이터에서 일반적인 컷아웃 구성을 다음과 같이 시뮬레이션할 수 있습니다.

  1. 개발자 옵션을 사용 설정합니다.
  2. 개발자 옵션 화면에서 드로잉 섹션까지 아래로 스크롤하고 컷아웃이 있는 디스플레이 시뮬레이션을 선택합니다.
  3. 컷아웃 유형을 선택합니다.

추가 리소스

디스플레이 컷아웃 지원에 관한 자세한 내용은 다음 링크를 참고하세요.