휴대전화에서는 앱 방향이 제한되지만 대형 화면에서는 제한되지 않음

별 2개 평점 아이콘

앱이 세로 모드의 휴대전화에서 잘 작동하므로 앱을 세로 모드로만 사용하도록 제한했습니다. 하지만 대형 화면의 가로 모드 방향으로 더 많은 작업을 할 수 있는 경우가 있습니다.

작은 화면에서는 세로 모드 방향으로 앱을 제한하고 대형 화면에서는 가로 모드를 사용할 수 있도록 두 가지 방법을 모두 제공하려면 어떻게 해야 할까요?

권장사항

우수한 앱은 기기 방향과 같은 사용자 선호도를 중요하게 생각합니다.

적응형 앱 품질 가이드라인에서는 앱이 세로 모드 방향, 가로 모드 방향, 멀티 윈도우 모드, 폴더블 기기의 접힌 상태와 펼친 상태를 비롯하여 모든 기기 설정을 지원할 것을 권장합니다. 앱은 다양한 구성에 맞게 레이아웃과 사용자 인터페이스를 최적화해야 하며, 구성을 변경하는 중에 상태를 저장하고 복원해야 합니다.

이 레시피는 대형 화면을 지원하기 위한 임시 조치입니다. 모든 기기 구성을 완벽하게 지원하도록 앱을 개선할 수 있게 되기까지 이 레시피를 사용하세요.

재료

  • screenOrientation: 앱이 기기 방향 변경에 응답하는 방식을 지정할 수 있는 앱 매니페스트 설정
  • Activity#setRequestedOrientation(): 런타임 시 앱 방향을 변경할 수 있게 해주는 메서드
  • LocalConfiguration: 현재 기기 Configuration을 노출하여 DP로 화면 크기를 읽을 수 있는 컴포저블 로컬 제공업체입니다.
  • LaunchedEffect: 키가 변경될 때 (이 경우 구성이 변경될 때) 코드 블록을 실행하는 Compose 부작용 API입니다.

단계

기본적으로 앱이 방향 변경을 처리하도록 앱 매니페스트에 사용 설정합니다. 그런 다음 런타임 시 Jetpack Compose를 사용하여 소형 화면 (휴대전화)에서 방향을 세로 모드로 동적으로 제한하는 동시에 대형 화면에서는 모든 방향을 허용합니다.

1. 앱 매니페스트에 방향 설정 지정

앱 매니페스트의 screenOrientation 요소를 선언하지 않거나 (이 경우 방향 기본값이 unspecified가 됨) 화면 방향을 fullUser로 설정할 수 있습니다. 사용자가 센서 기반 회전을 잠그지 않은 경우 앱은 모든 기기 방향을 지원합니다.

<activity
    android:name=".MyActivity"
    android:screenOrientation="fullUser">

unspecifiedfullUser 사용 간의 차이는 미묘하지만 중요합니다. screenOrientation 값을 선언하지 않으면 시스템에서 방향을 선택하고 시스템에서 방향을 정의하는 데 사용하는 정책은 기기마다 다를 수 있습니다. 반면에 fullUser를 지정하면 사용자가 기기에 정의한 동작에 더 가까워집니다. 사용자가 센서 기반 회전을 잠근 경우에는 앱이 사용자 환경설정을 따르고, 그러지 않은 경우에는 시스템이 네 가지 화면 방향 (세로, 가로, 세로 반전, 가로 반전)을 허용합니다. android:screenOrientation을 참고하세요.

2. Compose에서 방향 동적으로 제한

Jetpack Compose에서는 LocalConfiguration.current에서 현재 화면 크기를 DP로 반응형으로 읽고 LaunchedEffect를 사용하여 구성이 변경될 때마다 활동의 방향을 업데이트할 수 있습니다.

화면 너비 또는 높이가 600dp (휴대전화의 소형 중단점)보다 작으면 방향을 세로 모드로 제한합니다. 그렇지 않으면 시스템에서 사용자 환경설정 (unspecified 또는 fullUser)에 따라 앱을 회전하도록 허용합니다.

다음은 컴파일 가능한 전체 구현입니다.

val configuration = LocalConfiguration.current
val context = LocalActivity.current

LaunchedEffect(configuration) {
    val activity = context ?: return@LaunchedEffect
    // Determine if screen is compact (phone-sized) in either width or height
    val isCompact = configuration.screenWidthDp < 600 || configuration.screenHeightDp < 600
    activity.requestedOrientation = if (isCompact) {
        ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    } else {
        ActivityInfo.SCREEN_ORIENTATION_FULL_USER
    }
}

LaunchedEffect(configuration) 블록 내에 로직을 추가하면 활동 크기가 조절되거나 디스플레이 간에 이동하거나 폴더블 기기가 접히거나 펼쳐지는 등 앱 구성이 변경될 때마다 방향 설정을 반응형으로 재정의할 수 있습니다.

구성 변경이 발생하는 시점과 이러한 변경사항이 활동 재생성을 유발하는 시점에 관한 자세한 내용은 구성 변경사항 처리를 참고하세요.

결과

이제 앱이 작은 화면에서 기기 회전과 관계없이 세로 모드 방향으로 유지될 것입니다. 대형 화면에서는 앱이 가로 모드 방향과 세로 모드 방향을 지원합니다.

추가 리소스

항상 모든 기기 설정을 지원하도록 앱을 업그레이드하는 방법은 다음을 참고하세요.