Register now for Android Dev Summit 2019!

다양한 화면 크기 지원

Android 기기는 다양한 모양과 크기로 제공되므로 앱의 레이아웃이 유연해야 합니다. 레이아웃은 특정 화면 크기와 가로세로 비율을 가정하는 고정 크기로 정의되지 않아야 하며 다양한 화면 크기와 방향에 적절하게 반응해야 합니다.

앱은 단일 APK를 사용하여 가능한 한 많은 화면을 지원함으로써 최대한 많은 사용자가 다양한 기기에서 앱을 사용하도록 할 수 있습니다. 또한 앱이 유연하게 다양한 화면 크기를 지원하도록 하면 사용자가 멀티 윈도우 모드를 사용 설정하는 경우와 같이 기기의 창 구성 변경을 앱에서 처리할 수 있습니다.

이 페이지에서는 다음 기술을 사용하여 다양한 화면 크기를 지원하는 방법을 보여줍니다.

  • 레이아웃 크기 조정이 허용되는 뷰 크기 사용
  • 화면 구성에 따라 대체 UI 레이아웃 만들기
  • 뷰에서 확장할 수 있는 비트맵 제공

하지만 앱이 다양한 화면 크기에 맞게 조정된다고 해서 모든 Android 폼 팩터와 호환되는 것은 아닙니다. Android Wear, TV, Auto 및 Chrome OS 기기를 지원하려면 추가 단계를 수행해야 합니다.

다양한 화면의 UI를 빌드하기 위한 디자인 가이드라인은 반응형 UI에 대한 주요 가이드라인을 참조하세요.

유연한 레이아웃 만들기

지원하려는 하드웨어 프로필에 상관없이 우선 화면 크기의 작은 변화에도 반응하는 레이아웃을 만들어야 합니다.

ConstraintLayout 사용

다양한 화면 크기에 대한 반응형 레이아웃을 만드는 가장 좋은 방법은 ConstraintLayout을 UI의 기본 레이아웃으로 사용하는 것입니다. ConstraintLayout을 사용하면 레이아웃에 있는 다른 뷰와의 공간적 관계에 따라 각 뷰의 위치와 크기를 지정할 수 있습니다. 이러한 방식으로 화면 크기가 변경될 때 모든 뷰가 함께 이동하고 확장할 수 있습니다.

ConstraintLayout을 사용하여 레이아웃을 빌드하는 가장 쉬운 방법은 Android 스튜디오의 레이아웃 편집기를 사용하는 것입니다. 이 편집기에서는 XML을 직접 편집하지 않고도 새로운 뷰를 레이아웃으로 드래그하고, 상위 뷰 및 다른 동위 뷰에 해당 제약 조건을 첨부하고, 뷰 속성을 편집 할 수 있습니다(그림 1 참조).

자세한 정보는 ConstraintLayout으로 반응형 UI 빌드를 참조하세요.

그림 1. ConstraintLayout 파일을 보여주는 Android 스튜디오의 Layout Editor

ConstraintLayout으로 모든 레이아웃 시나리오를 해결할 수는 없지만(특히, 동적으로 로드되는 목록의 경우는 RecyclerView를 사용해야 함) 어떤 레이아웃을 사용하든 항상 하드 코딩 레이아웃 크기는 사용하지 않아야 합니다(다음 섹션 참조).

하드 코딩 레이아웃 크기 사용하지 않기

레이아웃이 유연하고 다양한 화면 크기에 맞게 조정되는지 확인하려면 대부분의 뷰 구성요소 너비 및 크기에 하드 코딩 크기가 아닌 "wrap_content""match_parent"를 사용해야 합니다.

"wrap_content"는 해당 뷰 내에 콘텐츠를 맞추는 데 필요한 크기로 뷰가 설정되도록 합니다.

"match_parent"는 뷰가 상위 뷰 내에서 가능한 한 크게 확장되도록 합니다.

예:

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/lorem_ipsum" />
    

이 뷰의 실제 레이아웃은 해당 상위 뷰 및 동위 뷰의 다른 속성에 따라 달라지지만 이 TextView는 해당 너비를 모든 사용 가능한 공간을 채우도록 설정하려고 하고(match_parent) 해당 높이를 정확히 텍스트 길이에 필요한 공간만큼으로 설정하려고 합니다(wrap_content). 이런 식으로 뷰가 다양한 화면 크기와 다양한 텍스트 길이에 맞게 조정될 수 있습니다.

그림 2는 기기 방향에 따라 화면 너비가 변경될 때 "match_parent"를 통해 텍스트 뷰 너비가 조정되는 방식을 보여줍니다.

그림 2. 유연한 텍스트 뷰

LinearLayout을 사용하는 경우 레이아웃 가중치도 있으면 각 뷰가 해당 가중치 값에 비례하게 나머지 공간을 채우도록 하위 뷰를 확장할 수 있습니다. 하지만 중첩 LinearLayout에서 가중치를 사용하려면 시스템이 여러 레이아웃 전달을 수행하여 각 뷰의 크기를 결정해야 하므로 UI 성능이 느려집니다. 다행히 ConstraintLayout은 성능에 영향을 미치지 않으면서 LinearLayout으로 가능한 거의 모든 레이아웃을 구현할 수 있으므로 레이아웃을 ConstraintLayout으로 변환해 보세요. 그런 다음, 제약 조건 체인을 사용하여 가중치 적용 레이아웃을 정의할 수 있습니다.

대체 레이아웃 만들기

레이아웃은 항상 해당 뷰 내부 및 주변에서 공간을 확장하여 다양한 화면 크기에 반응해야 하지만 이것만으로는 모든 화면 크기에 최상의 사용자 환경을 제공하지 못할 수도 있습니다. 예를 들어 스마트폰용으로 디자인한 UI는 태블릿에서는 좋은 환경을 제공하지 못할 수 있습니다. 따라서 앱은 특정 화면 크기에 맞게 디자인된 UI를 최적화할 대체 레이아웃 리소스도 제공해야 합니다.

그림 3. 동일한 앱이 서로 다른 화면 크기에서 각각 서로 다른 레이아웃 사용

서로 다른 레이아웃이 필요한 화면 구성마다 하나씩 추가 res/layout/ 디렉터리를 만든 후 화면 구성 한정자를 layout 디렉터리 이름에 추가하여(예: 사용 가능한 너비가 600dp인 화면의 경우 layout-w600dp) 화면 특정 레이아웃을 제공할 수 있습니다.

이러한 구성 한정자는 앱 UI에 사용 가능한 표시 화면 공간을 나타냅니다. 시스템은 앱에서 레이아웃을 선택할 때 시스템 장식(예: 탐색 메뉴) 및 창 구성 변경사항(예: 사용자가 멀티 윈도우 모드를 사용 설정한 경우)을 고려합니다.

Android 스튜디오(버전 3.0 이상 사용)에서 대체 레이아웃을 만들려면 다음을 수행합니다.

  1. 기본 레이아웃을 열고 툴바에서 Orientation for Preview 를 클릭합니다.
  2. 드롭다운 목록에서 Create Landscape Variant 같은 제안된 변형을 클릭하여 만들거나 Create Other를 클릭합니다.
  3. Create Other를 선택한 경우 Select Resource Directory가 나타납니다. 여기에서 왼쪽의 화면 한정자를 선택하여 Chosen qualifiers 목록에 추가합니다. 한정자 추가를 완료했으면 OK를 클릭합니다. (화면 크기 한정자에 대한 자세한 정보는 다음 섹션을 참조하세요.)

이렇게 하면 해당 레이아웃 디렉터리에 중복 레이아웃 파일이 만들어지므로 해당 화면 변형에 관해 레이아웃 맞춤설정을 시작할 수 있습니다.

최소 너비 한정자 사용

'최소 너비' 화면 크기 한정자를 사용하면 밀도 독립형 픽셀(dp 또는 dip) 단위로 측정된 최소 너비가 있는 화면에 대체 레이아웃을 제공할 수 있습니다.

밀도 독립형 픽셀 단위로 화면 크기를 설명하면 Android에서 아주 특정한 화면 크기로 디자인된 레이아웃을 만들 수 있을 뿐만 아니라 다양한 픽셀 밀도에 대해서도 염려할 필요가 없습니다.

예를 들어 디렉터리에서 다음과 같이 다양한 버전의 파일을 만들어 핸드셋과 태블릿에 최적화된 main_activity라는 레이아웃을 만들 수 있습니다.

    res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
    res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
    

최소 너비 한정자는 기기의 현재 방향에 상관없이 화면의 두 면이 가장 작은 것을 지정하므로 간단하게 레이아웃에 사용할 수 있는 전체 화면 크기를 지정할 수 있습니다.

다른 최소 너비 값에 해당하는 일반 화면 크기는 다음과 같습니다.

  • 320dp: 일반적인 전화 화면(240x320 ldpi, 320x480 mdpi, 480x800 hdpi 등).
  • 480dp: 대형 스마트폰 화면, 최대 5인치까지(480x800 mdpi).
  • 600dp: 7” 태블릿(600x1024 mdpi).
  • 720dp: 10” 태블릿(720x1280 mdpi, 800x1280 mdpi 등).

그림 4에서는 다양한 화면 dp 너비와 이에 해당하는 다양한 화면 크기 및 방향에 대한 자세한 뷰를 제공합니다.

그림 4. 다양한 화면 크기를 지원하는 권장 너비 중단점

최소 너비 한정자에 대한 모든 수치는 밀도 독립형 픽셀입니다. 중요한 것은 시스템이 픽셀 밀도(원시 픽셀 해상도 아님)를 고려한 후 사용 가능한 화면 공간 크기이기 때문입니다.

사용 가능한 너비 한정자 사용

화면의 최소 너비에 따라 레이아웃을 변경하는 것이 아니라, 현재 사용 가능한 너비 또는 높이에 따라 레이아웃을 변경할 수 있습니다. 예를 들어 창 두 개 레이아웃이 있으면 기기가 가로 모드 방향에 있는지 세로 모드 방향에 있는지에 따라 변경될 수 있는 화면의 너비가 최소 600dp가 될 때마다 이 창을 사용하려고 할 수 있습니다. 이 경우 다음과 같이 '사용 가능한 너비' 한정자를 사용해야 합니다.

    res/layout/main_activity.xml         # For handsets (smaller than 600dp available width)
    res/layout-w600dp/main_activity.xml  # For 7” tablets or any screen with 600dp
                                         #   available width (possibly landscape handsets)
    

사용 가능한 높이가 관건인 경우에는 '사용 가능한 높이' 한정자를 사용하여 동일하게 할 수 있습니다. 예를 들어 화면 높이가 600dp 이상인 화면의 경우 layout-h600dp입니다.

방향 한정자 추가

'최소 너비' 및 '사용 가능한 너비' 한정자의 조합만 사용하여 모든 크기 변형을 지원할 수도 있지만 사용자가 세로 방향과 가로 방향 간에 전환할 때 사용자 환경을 변경하고자 할 수도 있습니다.

이를 위해 리소스 디렉터리 이름에 port 또는 land 한정자를 추가할 수 있습니다. 이러한 한정자는 다른 크기 한정자 뒤에 오도록 해야 합니다. 예:

    res/layout/main_activity.xml                # For handsets
    res/layout-land/main_activity.xml           # For handsets in landscape
    res/layout-sw600dp/main_activity.xml        # For 7” tablets
    res/layout-sw600dp-land/main_activity.xml   # For 7” tablets in landscape
    

모든 화면 구성 한정자에 대한 자세한 정보는 리소스 제공 가이드의 표 2를 참조하세요.

프래그먼트로 UI 구성요소 모듈화

여러 화면 크기에 맞게 앱을 디자인할 때는 활동 전반에 걸쳐 불필요하게 UI 동작이 중복되지 않도록 해야 합니다. 그러므로 프래그먼트를 사용하여 UI 로직을 개별 구성요소로 추출하는 것이 좋습니다. 그런 다음 프래그먼트를 결합하여 큰 화면에서 실행할 때 다중창 레이아웃을 만들거나 핸드셋에서 실행할 때 개별 활동에 배치할 수 있습니다.

예를 들어 태블릿의 뉴스 앱은 왼쪽에 기사 목록을 표시하고 오른쪽에 특정 기사 전체를 표시할 수 있습니다. 왼쪽의 기사를 선택하면 오른쪽의 기사 보기가 업데이트됩니다. 하지만 핸드셋에서는 이러한 두 구성요소가 별개의 화면으로 표시되어야 합니다. 목록에서 기사를 선택하면 전체 화면이 변경되어 해당 기사가 표시됩니다.

자세히 알아보려면 프래그먼트로 동적 UI 빌드를 참조하세요.

레거시 크기 한정자로 Android 3.1 지원

앱이 Android 3.1(API 레벨 12) 이하를 지원하는 경우 위의 최소/사용 가능한 너비 한정자 외에도 레거시 크기 한정자를 사용해야 합니다.

위의 예에서 더 큰 기기에 창 두 개 레이아웃을 사용하려면 버전 3.1 이하를 지원하는 '대형' 구성 한정자를 사용해야 합니다. 따라서 이전 버전에서 이러한 레이아웃을 구현하려면 다음 파일이 필요할 수 있습니다.

    res/layout/main_activity.xml           # For handsets (smaller than 640dp x 480dp)
    res/layout-large/main_activity.xml     # For small tablets (640dp x 480dp and bigger)
    res/layout-xlarge/main_activity.xml    # For large tablets (960dp x 720dp and bigger)
    

레이아웃 별칭 사용

3.2 이전 및 3.2 이후 Android 버전을 모두 지원하는 경우 최소 너비 및 대형 한정자를 모두 레이아웃에 사용해야 합니다. 따라서 이름이 res/layout-large/main.xml인 파일을 보유하게 될 수 있고, 이 파일은 res/layout-sw600dp/main.xml과 동일할 수 있습니다.

이렇게 동일한 파일이 중복되지 않도록 하기 위해 별칭 파일을 사용할 수 있습니다. 예를 들어 다음 레이아웃을 정의할 수 있습니다.

    res/layout/main.xml            # single-pane layout
    res/layout/main_twopanes.xml   # two-pane layout
    

다음 파일 두 개를 추가합니다.

  • res/values-large/layout.xml:
        <resources>
            <item name="main" type="layout">@layout/main_twopanes</item>
        </resources>
        
  • res/values-sw600dp/layout.xml:
        <resources>
            <item name="main" type="layout">@layout/main_twopanes</item>
        </resources>
        

이러한 두 파일은 콘텐츠가 동일하지만 실제로 레이아웃을 정의하지는 않습니다. mainmain_twopanes의 별칭이 되도록 설정할 뿐입니다. 이러한 파일에는 largesw600dp 선택기가 있으므로 Android 버전과 관계없이 대형 화면에 적용됩니다(3.2 이전 태블릿과 TV는 large와 일치하고 3.2 이후 버전은 sw600dp와 일치함).

늘릴 수 있는 나인 패치 비트맵 만들기

크기가 변경되는 뷰의 백그라운드로 비트맵을 사용하는 경우 뷰의 화면 또는 콘텐츠의 크기에 따라 뷰가 확장되거나 축소될 때 Android에서 이미지의 크기를 조정합니다. 이 경우 블러 또는 다른 조정 아티팩트가 표시되는 경우가 많습니다. 이 문제를 해결하는 방법은 나인 패치 비트맵을 사용하는 것입니다. 나인 패치 비트맵은 늘릴 수 있는 영역과 늘릴 수 없는 영역을 나타내는 특수한 형식의 PNG 파일입니다.

나인 패치 비트맵은 기본적으로 표준 PNG 파일이지만 늘려야 하는 픽셀을 나타내는 추가 1px 테두리가 있습니다(또한, 확장자도 그냥 .png가 아니라 .9.png임). 그림 5에 표시된 것처럼, 왼쪽 및 위쪽 가장자리 검은 선 사이의 교차 부분은 늘릴 수 있는 비트맵 영역입니다.

선택적으로 오른쪽 및 아래쪽 가장자리에 선을 유사한 방식으로 추가하여 콘텐츠가 뷰 안에 표시되도록 보장하는 안전 영역을 정의할 수도 있습니다.

그림 5. 나인 패치 이미지(button.9.png)

나인 패치를 뷰의 백그라운드로 적용하는 경우 프레임워크가 버튼 크기에 맞게 이미지를 올바른 크기로 늘립니다.

비트맵에서 나인 패치 이미지를 만드는 방법에 대한 도움말은 크기 조정 가능한 비트맵 만들기를 참조하세요.

모든 화면 크기로 테스트

다양한 화면 크기로 앱을 테스트하여 UI 크기 조정이 제대로 이루어지도록 하는 것이 중요합니다. 모든 다양한 화면 크기의 실제 기기에 액세스할 수 없다면 Android 에뮬레이터를 사용하여 원하는 화면 크기를 에뮬레이션할 수 있습니다.

실제 기기에서 테스트하고 싶지만 기기를 구매하고 싶지 않은 경우에는 Firebase Test Lab을 사용하여 Google 데이터 센터의 기기에 액세스할 수 있습니다.

특정 화면 크기 지원 선언

앱을 특정 화면 크기에서 실행하지 않으려면 화면 크기를 조정해야 하는 제한을 설정하거나 화면 구성에 따라 앱을 설치할 수 있는 기기를 제한할 수 있습니다. 자세한 정보는 제한된 화면 지원 선언을 참조하세요.