창 관리

ChromeOS는 여러 창에서 Android 앱을 지원합니다. 시스템은 그림 1과 같이 기기의 폼 팩터에 따라 크기가 결정되는 창 컨테이너에 앱을 렌더링합니다.

그림 1. 여러 기기의 앱 창

다양한 화면 크기에서 작동하는 레이아웃을 디자인하는 것이 중요합니다. Android 가이드라인에 따라 다양한 화면 크기를 지원하면 앱이 ChromeOS에서 실행될 때도 원활하게 작동합니다.

이 페이지에서는 앱의 창이 올바르게 시작되고, 크기가 원활하게 조정되며, 크기가 변경될 때 모든 콘텐츠를 표시하는 방법을 보여줍니다.

최초 시작 크기

앱은 다음과 같은 방법으로 초기 시작 크기를 요청할 수 있습니다.

  • 데스크톱 환경에서만 시작 크기를 사용합니다. 이렇게 하면 창 관리자가 적절한 경계와 방향을 제공하는 데 도움이 됩니다. 데스크톱 모드로 사용될 때 환경설정을 표시하려면 <activity> 내에 다음 메타 태그를 추가합니다.
<meta-data android:name="WindowManagerPreference:FreeformWindowSize"
           android:value="[phone|tablet|maximize]" />
<meta-data android:name="WindowManagerPreference:FreeformWindowOrientation"
           android:value="[portrait|landscape]" />
  • 정적 시작 경계를 사용합니다. 다음 예와 같이 활동의 매니페스트 항목 내에서 <layout>를 사용하여 '고정' 시작 크기를 지정합니다.
<layout android:defaultHeight="500dp"
            android:defaultWidth="600dp"
            android:gravity="top|end"
            android:minHeight="450dp"
            android:minWidth="300dp" />
  • 동적 시작 경계를 사용합니다. 새 활동을 만들 때 활동이 ActivityOptions.setLaunchBounds(Rect)를 만들어 사용할 수 있습니다. 빈 직사각형을 지정하여 앱을 최대화할 수 있습니다.

창 크기 조절

ChromeOS에서 사용자는 일반적인 방법, 즉 그림 2와 같이 오른쪽 하단 모서리를 드래그하여 앱 창 크기를 조절할 수 있습니다.

그림 2. 크기 조절 가능한 앱 창

View 클래스를 사용할 때 창 크기 조절을 처리하는 옵션으로는 두 가지가 있습니다.

  • onConfigurationChanged(..)를 호출하여 구성 변경에 동적으로 응답합니다. 예를 들어 활동의 매니페스트에 android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"를 추가할 수 있습니다. 구성 변경 처리에 관한 자세한 내용은 구성 변경 처리를 참고하세요.
  • 시스템이 활동을 다시 시작하도록 합니다. 이 경우 onSaveInstanceState를 구현하고 ViewModel 아키텍처 구성요소를 사용하여 이전에 저장된 상태를 복원합니다.

Jetpack Compose를 사용하는 경우 크기 조절 동작은 활동 구성 방식에 따라 달라집니다. 변경사항을 동적으로 처리하는 경우 창 크기가 변경될 때 리컴포지션이 트리거됩니다. 활동이 시스템에서 다시 시작하면 다시 시작한 후에 초기 컴포지션이 발생합니다. 어느 쪽이든 창 크기 변경에 맞게 조정되는 Compose 레이아웃을 만드는 것이 중요합니다. 고정된 크기를 가정하지 않습니다.

창 크기

활동이 시작될 때마다 창 크기를 읽고 현재 구성에 따라 콘텐츠를 정렬하도록 합니다.

현재 구성을 확인하려면 현재 활동에서 getResources().getConfiguration()을 호출합니다. 백그라운드 활동이나 시스템 리소스의 구성을 사용하지 마세요. 백그라운드 활동에는 크기가 없으며 시스템 구성에 크기와 방향이 충돌하는 여러 창이 포함되어 있을 수 있으므로 사용 가능한 데이터를 추출할 수 없습니다.

크기와 화면 크기는 동일하지 않습니다. DP에 창 크기를 가져오려면 Activity.getResources().getConfiguration().screenWidthActivity.getResources().getConfiguration().screenHeight를 사용해야 합니다. 화면 크기는 사용하지 않아도 될 것입니다.

콘텐츠 경계

창의 콘텐츠 경계는 크기 조절 후 변경될 수 있습니다. 예를 들어 창이 너무 커져서 화면에 다 들어가지 않으면 앱에서 사용하는 창 내의 영역이 변경될 수 있습니다. 다음 가이드라인을 준수하세요.

  • Android의 레이아웃 프로세스를 사용하는 앱은 사용 가능한 공간에 자동으로 배치됩니다.
  • 네이티브 앱은 UI 요소에 액세스할 수 없는 상황이 발생하지 않도록 사용 가능한 영역을 읽고 크기 변경을 모니터링해야 합니다. 이 표시 화면에 사용 가능한 최초 크기를 확인하려면 다음 메서드를 호출합니다.

    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()

    관찰자를 사용하여 지속적으로 모니터링할 수 있습니다.

    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • view.addOnLayoutChangeListener(findViewById(android.R.id.content))에 리스너 추가

    앱에서 아트워크의 크기를 사전 조정하는 경우 해상도가 변경될 때마다 크기를 조정합니다.

자유 형식 크기 조절

ChromeOS를 사용하면 모든 창의 크기를 자유롭게 조절할 수 있습니다. 사용자가 창의 너비, 높이, 화면에서의 위치를 변경할 수 있습니다. 많은 Android 앱은 자유 형식 크기 조절을 염두에 두지 않고 작성됩니다. 다음과 같은 문제를 고려하세요.

  • 화면 위치가 변경될 수 있습니다. 항상 시스템을 사용하여 창에서 화면으로 그리고 화면에서 창으로 좌표 변환을 실행해야 합니다.
  • Android의 뷰 시스템을 사용하는 경우 크기가 변경되면 창 레이아웃이 자동으로 변경됩니다.
  • 뷰 시스템을 사용하지 않고 노출 영역을 인계받으면 앱이 자체적으로 크기 변경을 처리해야 합니다.
  • 네이티브 앱의 경우 mLastContent 멤버를 사용하거나 콘텐츠 뷰를 사용하여 초기 크기를 결정합니다.
  • 앱이 실행 중일 때 onContentRectChangedNative 또는 onGlobalLayout 이벤트를 수신 대기하여 크기 변경에 반응합니다.
  • 앱의 크기가 변경되면 레이아웃과 아트워크를 재조정하거나 새로고침하고 입력 영역을 업데이트합니다.

전체 화면 모드

전체 화면 모드는 스톡 Android에서와 동일하게 작동합니다. 창이 전체 화면을 가리지 않으면 전체 화면(모든 시스템 UI 요소 숨기기) 요청이 무시됩니다. 앱이 최대화되면 일반적인 전체 화면 메서드, 레이아웃 및 함수가 실행됩니다. 이렇게 하면 시스템 UI 요소(창 컨트롤 바 및 실행기)가 숨겨집니다.

화면 방향

Android 앱의 가장 일반적인 방향은 세로 모드입니다. 사용자가 대부분 세로 방향으로 스마트폰을 잡고 사용하기 때문입니다. 세로 모드는 스마트폰에 적합하지만 가로 모드가 더 일반적인 노트북과 태블릿에서는 적합하지 않습니다. 앱에서 최상의 결과를 얻으려면 두 방향을 모두 지원하는 것이 좋습니다.

일부 Android 앱에서는 기기가 세로 모드로 유지될 때 회전 값이 Surface.ROTATION_0이라고 가정합니다. 이는 대부분의 Android 기기에 적용됩니다. 그러나 앱이 특정 ARC 모드에 있을 때 세로 방향의 회전 값은 Surface.ROTATION_0가 아닐 수도 있습니다.

가속도계 또는 유사한 센서를 읽는 동안 정확한 회전 값을 얻으려면 Display.getRotation() 메서드를 사용하고 그에 따라 축을 전환하세요.

루트 활동 및 방향

Chromebook 창은 활동 창의 스택으로 구성되어 있습니다. 스택의 각 창은 크기 및 방향이 동일합니다.

데스크톱 환경에서 갑작스러운 방향 및 크기 변경은 혼란을 야기할 수 있습니다. Chromebook 창 관리자는 Android의 병렬 모드와 유사한 방식으로 이를 방지합니다. 스택의 맨 아래에 있는 활동이 위에 있는 모든 활동의 속성을 제어합니다. 이로 인해 세로 모드이고 크기 조절이 불가능한 새로 시작된 활동이 가로 모드 및 크기 조절 가능한 상태가 되는 예기치 않은 상황이 발생할 수 있습니다.

기기 모드가 여기에 영향을 미칩니다. 태블릿 모드에서는 방향이 잠겨 있지 않으며 각 창은 Android에서 일반적으로 그러하듯 자체 방향을 유지합니다.

방향 가이드라인

방향 처리를 위해 다음 가이드라인을 준수하세요.

  • 한 방향만 지원한다면 애플리케이션을 시작하기 전에 창 관리자가 이를 알 수 있도록 매니페스트에 정보를 추가합니다. 방향을 지정할 때 가능하면 센서 방향도 지정합니다. Chromebook은 컨버터블인 경우가 많으며 거꾸로 된 앱은 사용자 경험을 저해합니다.
  • 선택한 단일 방향으로 유지하세요. 매니페스트에서 특정한 한 방향을 요청하고 나중에 프로그램상에서 다른 방향을 설정하면 안 됩니다.
  • 창 크기에 따라 방향 변경 시 주의해야 합니다. 사용자가 작은 세로 모드 크기 창에서 멈춰서 더 큰 가로 모드 창으로 돌아가지 못할 수 있습니다.
  • Chrome에는 사용 가능한 모든 레이아웃 간에 전환할 수 있는 창 컨트롤이 있습니다. 올바른 방향 옵션을 선택하면 앱을 실행한 후 사용자가 올바른 레이아웃을 사용하도록 할 수 있습니다. 세로 모드 및 가로 모드로 앱을 사용할 수 있는 경우 가능하면 기본값을 가로 모드로 설정하세요. 이 옵션이 설정되면 앱별로 설정이 유지됩니다.
  • 불필요한 방향 변경은 피하세요. 예를 들어 활동 방향이 세로 모드이지만 앱이 런타임에 setRequestedOrientation(LANDSCAPE)를 호출하면 불필요한 창 크기 조절이 발생하여 사용자에게 불편을 주고 앱에서 이를 처리하지 못하는 앱을 다시 시작할 수 있습니다. 매니페스트 등에서 방향을 한 번 설정하고 필요한 경우에만 변경하는 것이 좋습니다.

기타 고려사항

다음은 ChromeOS에서 Android 앱으로 작업할 때 고려해야 할 다른 몇 가지 사항입니다.

  • 활동의 onDestroy 메서드에서 finish()를 호출하지 마세요. 이렇게 하면 크기 조절 시 앱이 닫히고 다시 시작되지 않습니다.
  • TYPE_KEYGUARDTYPE_APPLICATION_MEDIA와 같이 호환되지 않는 창 유형은 사용하지 마세요.
  • 이전에 할당된 객체를 캐싱하여 활동이 빠르게 다시 시작되도록 합니다.
  • 사용자가 앱 크기를 조절하지 못하게 하려면 매니페스트 파일에 android:resizeableActivity=false를 지정합니다.
  • 앱을 테스트하여 창 크기 변경을 적절하게 처리하는지 확인합니다.