The Android Developer Challenge is back! Submit your idea before December 2.

앱 리소스 개요

리소스는 코드에서 사용하는 추가 파일과 정적인 콘텐츠입니다. 예를 들어 비트맵, 레이아웃 정의, 사용자 인터페이스 문자열, 애니메이션 지침 등이 있습니다.

이미지나 문자열과 같은 앱 리소스는 항상 코드에서 외부화해야 합니다. 그래야 이들을 독립적으로 유지관리할 수 있습니다. 특정 기기 구성에 대한 대체 리소스도 제공해야 합니다. 이것은 특별하게 명명한 리소스 디렉토리에 그룹화하는 방법을 씁니다. Android는 런타임에 현재 구성을 근거로 적절한 리소스를 사용합니다. 예를 들어 여러 가지 화면 크기에 따라 여러 가지 UI 레이아웃을 제공하거나 언어 설정에 따라 각기 다른 문자열을 제공하고자 할 수 있습니다.

앱 리소스를 외부화하면 프로젝트 R 클래스에서 발생하는 리소스 ID로 액세스할 수 있습니다. 이 문서에서는 Android 프로젝트에서 리소스를 그룹화하고, 특정 기기 구성에 대한 대체 리소스를 제공한 다음, 앱 코드나 다른 XML 파일에서 액세스하는 방법을 보여줍니다.

리소스 유형 그룹화

프로젝트의 res/ 디렉토리에 속한 특정 하위 디렉토리에 각 유형의 리소스를 배치해야 합니다. 예를 들어, 다음은 간단한 프로젝트의 파일 계층입니다.

MyProject/
    src/
        MyActivity.java
    res/
        drawable/
            graphic.png
        layout/
            main.xml
            info.xml
        mipmap/
            icon.png
        values/
            strings.xml

이 예시에서는 res/ 디렉토리가 모든 리소스(이미지 리소스 한 개, 레이아웃 리소스 두 개, 런처 아이콘용 mipmap/ 디렉토리, 문자열 리소스 파일 한 개)를 하위 디렉토리에 포함합니다. 리소스 디렉토리 이름은 중요하며, 표1에 설명되어 있습니다.

참고: Mipmap 폴더를 사용하는 자세한 방법은 프로젝트 관리 개요를 참조하세요.

표 1. 프로젝트 res/ 디렉토리 내부에서 지원되는 리소스 디렉토리.

디렉토리 리소스 유형
animator/ 속성 애니메이션을 정의하는 XML 파일입니다.
anim/ tween 애니메이션을 정의하는 XML 파일입니다. (속성 애니메이션도 이 디렉토리에 저장할 수 있지만 두 가지 유형을 구분하기 위해 속성 애니메이션은 animator/ 디렉토리에 저장하는 것이 좋습니다.)
color/ 색상의 상태 목록을 정의하는 XML 파일입니다. 색상 상태목록 리소스를 참조하세요.
drawable/

다음 드로어블 리소스 하위 유형으로 컴파일되는 비트맵 파일(.png, .9.png, .jpg, .gif) 또는 XML 파일입니다.

  • 비트맵 파일
  • 나인 패치(크기 조절 가능한 비트맵)
  • 상태 목록
  • 셰이프
  • 드로어블 애니메이션
  • 기타 드로어블

드로어블 리소스를 참조하세요.

mipmap/ 각기 다른 시작 관리자 아이콘 밀도에 대한 드로어블 파일입니다. mipmap/ 폴더로 런처 아이콘을 관리하는 방법에 대한 자세한 내용은 프로젝트 관리 개요를 참조하세요.
layout/ 사용자 인터페이스 레이아웃을 정의하는 XML 파일입니다. 레이아웃 리소스를 참조하세요.
menu/ 옵션 메뉴, 컨텍스트 메뉴 또는 하위메뉴 등과 같은 앱 메뉴를 정의하는 XML 파일입니다. 메뉴 리소스를 참조하세요.
raw/

원시 형태로 저장하기 위한 임의의 파일입니다. 원시 InputStream으로 이러한 리소스를 열려면 리소스 ID(R.raw.filename)를 사용하여 Resources.openRawResource()를 호출합니다.

그러나 원본 파일 이름과 파일 계층에 액세스해야 하는 경우, res/raw/ 대신 assets/ 디렉토리에 일부 리소스를 저장해두는 것도 고려해볼 수 있습니다. assets/에 있는 파일에는 리소스 ID가 부여되지 않으므로, AssetManager를 사용해야 이 파일들을 읽을 수 있습니다.

values/

문자열, 정수 및 색과 같은 단순 값이 들어 있는 XML 파일입니다.

다른 res/ 하위 디렉토리에 있는 XML 리소스 파일은 XML 파일 이름을 근거로 하나의 리소스를 정의하는 반면, values/ 디렉토리에 있는 파일은 여러 개의 리소스를 설명합니다. 이 디렉토리 안에 있는 파일의 경우, 요소의 각 하위 요소가 리소스를 하나씩 정의합니다. 이 디렉토리에 속하는 파일의 경우, <resources> 요소의 각 하위요소가 하나의 리소스를 정의합니다. 예를 들어 <string> 요소는 R.string 리소스를 생성하고 <color> 요소는 R.color 리소스를 생성합니다.

각 리소스가 자체 XML 요소로 정의되므로, 원하는 대로 파일을 정의하고 하나의 파일에 여러 가지 리소스 유형을 배정할 수 있습니다. 하지만 명확히 하려면 여러 가지 파일에 각기 고유한 리소스를 배치하는 것이 좋을 수도 있습니다. 예를 들어, 다음은 이 디렉토리에서 생성할 수 있는 리소스를 위한 파일 이름 지정 규칙입니다.

문자열 리소스, 스타일 리소스자세한 리소스 유형을 참조하세요.

xml/ Resources.getXML()을 호출하여 런타임에 읽을 수 있는 임의의 XML 파일입니다. 다양한 XML 구성 파일을 여기에 저장해야 합니다. 예를 들어 검색 가능한 구성 등이 이에 해당됩니다.
font/ .ttf, .otf 또는 .ttc 확장자가 붙은 글꼴 파일이나 <font-family> 요소를 포함한 XML 파일. 리소스로서의 글꼴에 대한 자세한 내용은 XML의 글꼴을 참조하세요.

주의: 리소스 파일을 res/ 디렉토리에 직접 저장하면 절대로 안 됩니다. 컴파일러 오류가 발생합니다.

특정 유형의 리소스에 관한 자세한 정보는 리소스 유형 문서를 참조하세요.

표 1에 정의된 하위 디렉토리에 저장하는 리소스는 "기본" 리소스입니다. 즉, 이 리소스는 앱의 기본 디자인과 콘텐츠를 정의합니다. 다만 여러 가지 유형의 Android 지원 기기마다 서로 다른 유형의 리소스를 필요로 할 수 있습니다. 예를 들어 기기의 화면이 일반적인 화면보다 큰 경우에는 그러한 추가적인 화면 공간을 유리하게 활용할 수 있는 다른 레이아웃 리소스를 제공해야 합니다. 또는, 기기에 다른 언어 설정이 있을 경우 해당 텍스트를 사용자 인터페이스에 번역하는 다른 문자열 리소스를 제공해야 합니다. 기기 구성에 따라 다른 리소스를 제공하려면, 기본 리소스 외에 대체 리소스를 제공해야 합니다.

대체 리소스 제공

거의 모든 앱이 특정 기기 구성을 지원하는 대체 리소스를 제공해야 합니다. 예를 들어 여러 가지 화면 밀도에 맞는 대체 드로어블 리소스를 포함해야 하며 여러 가지 언어에 맞게 대체 문자열 리소스도 포함시켜야 합니다. Android는 런타임에 현재 기기 구성을 감지하고 앱에 대해 적절한 리소스를 로드합니다.

그림 1. 각각 다른 레이아웃 리소스를 사용하는 서로 다른 두 개의 기기.

리소스 세트에 대하여 구성별로 적절한 대체를 지정하려면 다음과 같이 합니다.

  1. res/<resources_name>-<config_qualifier> 형식으로 이름을 지정하여 새 디렉토리를 만듭니다.
    • <resources_name>은 해당 기본 리소스의 디렉토리 이름입니다(표 1에 정의되어 있음).
    • <qualifier>는 리소스를 사용할 개별 구성을 지정하는 이름입니다(표 2에 정의되어 있음).

    하나 이상의 <qualifier>를 추가할 수 있습니다. 각각 대시로 구분합니다.

    주의: 여러 한정자를 추가할 때는 표 2에 나열된 것과 같은 순서로 배치해야 합니다. 한정자의 순서가 잘못 지정되면 해당 리소스가 무시됩니다.

  2. 해당되는 각 대체 리소스를 이 새 디렉토리에 저장하세요. 이 리소스 파일은 기본 리소스 파일과 똑같은 이름을 지정해야 합니다.

예를 들어 다음은 기본 리소스와 대체 리소스입니다.

res/
    drawable/
        icon.png
        background.png
    drawable-hdpi/
        icon.png
        background.png

hdpi 한정자는 해당 디렉토리의 리소스가 고화질 화면 기기용이라는 것을 나타냅니다. 각 드로어블 디렉토리의 이미지는 특정 화면 화질에 맞추어 크기가 지정되었으나 파일 이름은 똑같습니다. 이렇게 하면 icon.png 또는 background.png 이미지를 참조하는 데 사용하는 리소스 ID는 항상 같지만 Android가 각 리소스 중에서 현재 기기에 가장 잘 일치하는 버전을 선택하게 됩니다. 이때 리소스 디렉토리 이름의 한정자를 기기 구성 정보와 비교하는 방법을 씁니다.

Android는 여러 가지 구성 한정자를 지원하며 한 디렉토리 이름에 여러 개의 한정자를 추가할 수 있습니다. 각 한정자를 대시로 구분하면 됩니다. 표 2는 유효한 구성 한정자를 우선순위대로 나열한 것입니다. 리소스 디렉토리에 여러 개의 한정자를 사용하는 경우, 해당 한정자를 디렉토리 이름에 추가할 때 이 표에 나열된 것과 같은 순서로 추가해야 합니다.

표 2. 구성 한정자 이름.

구성 한정자 값 설명
MCC 및 MNC 예:
mcc310
mcc310-mnc004
mcc208-mnc00
등.

이동통신 국가 코드(MCC)에 선택적으로 이동통신 네트워크 코드(MNC)가 이어지는 형태로, 기기의 SIM 카드에서 가져옵니다. 예를 들어 mcc310은 모든 이동 통신사를 포함한 미국이고, mcc310-mnc004는 Verizon을 사용하는 미국, mcc208-mnc00은 Orange를 사용하는 프랑스입니다.

기기가 무선 연결(GSM 전화)을 사용할 경우, MCC와 MNC 값은 SIM 카드에서 가져옵니다.

MCC만 단독으로 사용할 수도 있습니다(예를 들어 앱에 국가별 합법적 리소스를 포함하는 경우). 언어에만 기초해서 지정해야 할 경우, 언어 및 지역 한정자를 대신 사용합니다(아래에 설명). MCC와 MNC 한정자를 사용할 경우, 신중하게 사용하고 예상한 대로 작동하는지 테스트해야 합니다.

또한, 구성 필드 mccmnc를 참조하세요. 이 구성 필드는 각각 모바일 국가 코드와 모바일 네트워크 코드를 나타냅니다.

언어 및 지역 예:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419

언어는 두 글자의 ISO639-1 언어 코드로 정의되고, 뒤이어 두 글자의 ISO3166-1-alpha-2 지역 코드(앞에 소문자 'r'이 추가됨)가 선택적으로 따라옵니다.

코드는 대소문자를 구별하지 않습니다. r 접두어는 지역 부분을 구별하기 위해 사용됩니다. 지역만 지정할 수는 없습니다.

Android 7.0(API 레벨 24)에서는 BCP 47 언어 태그에 대한 지원이 추가되었습니다. 이 태그를 사용하여 언어 및 지역별 리소스를 정규화할 수 있습니다. 언어 태그 하나는 하나 이상의 하위 태그 시퀀스로 구성됩니다. 각각의 하위 태그는 전체 태그로 식별되는 언어의 범위를 구체화하거나 좁히는 역할을 합니다. 언어 태그에 대한 자세한 내용은 언어 식별을 위한 태그를 참조하세요.

BCP 47 언어 태그를 사용하려면 b+와 두 글자의 ISO 639-1 언어 코드를 결합합니다. +로 구분한 추가적인 하위 태그를 뒤에 옵션으로 덧붙일 수도 있습니다.

사용자가 시스템 설정에서 언어를 변경하면 앱의 수명 주기가 남아 있는 동안 언어 태그가 변경될 수 있습니다. 런타임에서 앱에 어떤 영향을 미치는지 자세히 알아보려면 런타임 변경 처리를 참조하세요.

다른 여러 언어에 맞게 앱을 현지화하기 위한 전체 지침은 현지화를 참조하세요.

정의된 로케일 목록을 제공하는 getLocales() 메서드도 참조하세요. 이 목록에는 기본 로케일이 포함됩니다.

레이아웃 방향 ldrtl
ldltr

앱의 레이아웃 방향입니다. ldrtl는 "오른쪽에서 왼쪽 방향 레이아웃"을 나타냅니다. ldltr는 "왼쪽에서 오른쪽 방향 레이아웃"을 나타내고 기본 암시적 값입니다.

이는 레이아웃이나 드로어블, 값 등의 모든 리소스에 적용할 수 있습니다.

예를 들어, 아랍어에 대한 특정 레이아웃을 제공하고 다른 "오른쪽에서 왼쪽으로 쓰는" 언어(히브리어 또는 페르시아어)에 제네릭 레이아웃을 제공하고 싶다면 다음과 같이 해야 합니다.

res/
    layout/
        main.xml (Default layout)
    layout-ar/
        main.xml (Specific layout for Arabic)
    layout-ldrtl/
        main.xml (Any "right-to-left" language, except
                  for Arabic, because the "ar" language qualifier
                  has a higher precedence.)

참고: 앱에서 오른쪽에서 왼쪽 레이아웃 기능을 활성화하려면 supportsRtl"true"로 설정하고 targetSdkVersion을 17 이상으로 설정해야 합니다.

API 레벨 17에서 추가되었습니다.

smallestWidth sw<N>dp

예:
sw320dp
sw600dp
sw720dp
등.

화면의 기본 크기로, 사용 가능한 화면 영역의 가장 짧은 치수로 나타냅니다. 구체적으로 기기의 smallestWidth는 해당 화면의 이용 가능한 높이와 너비의 가장 짧은 치수를 말합니다(이것을 화면에 대한 '가능한 한 가장 좁은 너비'로 생각해도 됩니다). 이 한정자를 사용하면 화면의 현재 방향에 관계없이 해당 UI에 사용 가능한 너비 중 최소 <N>dp를 앱에 확보할 수 있습니다.

예를 들어 언제나 최소 600dp에서 최소 치수의 화면 공간이 레이아웃에 필요한 경우, 이 한정자를 사용하여 레이아웃 리소스, res/layout-sw600dp/를 만들 수 있습니다. 시스템은 사용 가능한 화면의 최소 치수가 600dp인 경우에만 이런 리소스를 사용하고, 이때 사용자 쪽에서 600dp가 높이이든 너비이든 관계없습니다. 이 최소 너비는 기기의 고정된 화면 크기 특성입니다. 기기의 최소 너비는 화면 방향이 변경되어도 바뀌지 않습니다.

레이아웃 디자인에서 흔히 너비가 구동 인자로 사용되므로 최소 너비를 사용하여 일반 화면 크기를 결정하는 방법이 유용합니다. 대개 UI는 세로로 스크롤되지만, 가로로 스크롤될 경우 최소 공간에 대한 제약이 상당합니다. 핸드셋용 단일 창 레이아웃을 사용할지, 태블릿용 다중 창 레이아웃을 사용할지 여부를 결정할 때는 사용 가능한 너비도 중요한 요소입니다. 따라서 아마도 여러분이 가장 신경 쓰는 것은 각 기기에서 사용 가능한 최소 너비일 것입니다.

기기의 최소 너비는 화면 장식과 시스템 UI를 감안합니다. 예를 들어 화면상에서 최소 너비의 축 주변 공간을 차지하는 영구 UI 요소가 있다면 시스템은 최소 너비를 실제 화면 크기보다 작게 선언합니다. 이것은 개발자의 UI가 사용할 수 없는 화면 픽셀이기 때문입니다.

다음과 같은 일부 값은 일반적인 화면 크기에 사용할 수 있습니다.

  • 화면 크기 320에 화면 구성이 아래와 같은 기기:
    • 240x320ldpi(QVGA 핸드셋)
    • 320x480mdpi(핸드셋)
    • 480x800hdpi(고화질 핸드셋)
  • 480x800mdpi(태블릿/핸드셋) 등의 화면에는 480을 사용합니다.
  • 600x1024mdpi (7인치 태블릿) 등의 화면에는 600을 사용합니다.
  • 720x1280mdpi(10인치 태블릿) 등의 화면에는 720을 사용합니다.

앱이 smallestWidth 한정자의 여러 값이 포함된 여러 개의 리소스 디렉토리를 제공하면 시스템은 기기의 smallestWidth에 가장 가깝지만 이를 초과하지 않는 값을 사용합니다.

API 레벨 13에서 추가되었습니다.

그 외에도 앱과 호환되는 최소한의 smallestWidth를 선언하는 android:requiresSmallestWidthDp 특성과 기기의 smallestWidth 값을 유지하는 smallestScreenWidthDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 내용은 다중 화면지원 개발자 가이드를 참조하세요.

이용 가능한 너비 w<N>dp

예:
w720dp
w1024dp
등.

리소스를 사용해야 하는 dp 단위에서 최소 이용 가능한 화면 너비를 지정합니다. 이는 <N> 값으로 정의됩니다. 이 구성 값은 현재 실제 너비에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때 변경됩니다.

대개 이 방법은 다중 창 레이아웃의 사용 여부를 결정할 때 유용합니다. 아무리 태블릿 기기라고 해도 가로 모드와 세로 모드 방향에 동일한 다중 창 레이아웃을 원하지는 않을 것입니다. 따라서 이 방법을 사용하면 화면 크기와 방향 한정자를 함께 사용하는 대신, 레이아웃에 필요한 최소 너비를 지정할 수 있습니다.

앱이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉토리를 제공하면, 시스템은 기기의 현재 화면 너비에 가장 가깝지만 이를 초과하지 않는 값을 사용합니다. 이 값은 화면 장식을 감안한 것이므로 기기의 왼쪽이나 오른쪽 가장자리에 영구 UI 요소가 있을 경우, 기기는 이러한 UI 요소를 감안하여 앱의 이용 가능한 공간을 줄이고 실제 화면 크기보다 작은 너비 값을 사용합니다.

API 레벨 13에서 추가되었습니다.

현재 화면 너비를 보유한 screenWidthDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 내용은 다중 화면지원 개발자 가이드를 참조하세요.

이용 가능한 높이 h<N>dp

예:
h720dp
h1024dp
등.

리소스가 사용되어야 하는 최소한의 사용 가능한 화면 높이를 "dp" 단위로 나타냅니다. 이는 <N> 값이 정의합니다. 이 구성 값은 현재 실제 높이에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때 변경됩니다.

이 방법을 사용하여 레이아웃에 필요한 높이를 정의하는 것은 화면 크기와 방향 한정자를 함께 사용하는 대신 w<N>dp를 사용하여 필요한 너비를 정의하는 것과 마찬가지로 유용한 방법입니다. 그러나 대개 UI는 세로로 스크롤되므로 너비는 다소 경직적인 데 반해 사용 가능한 높이에는 좀 더 유연성이 있다는 점을 고려하면, 대부분의 앱에는 이 한정자가 필요 없습니다.

앱이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉토리를 제공하면, 시스템은 기기의 현재 화면 높이에 가장 가깝지만 이를 초과하지 않는 값을 사용합니다. 이 값은 화면 장식을 감안한 것이므로 기기의 상단이나 하단 가장자리에 영구 UI 요소가 있을 경우, 기기는 이러한 UI 요소를 감안하여 앱의 이용 가능한 공간을 줄여서 실제 화면 크기보다 작은 높이 값을 사용합니다. 상태 표시줄에 고정되지 않은 화면 장식(예를 들어 전화 상태 표시줄은 전체 화면에서 숨길 수 있음)은 여기에서 감안하지 않았고 제목 표시줄이나 작업 모음 등의 창 장식도 감안하지 않았으므로, 앱은 지정된 것보다 어느 정도 공간이 작아질 것에 대비해야 합니다.

API 레벨 13에서 추가되었습니다.

현재 화면 너비를 보유한 screenHeightDp 구성 필드도 참조하세요.

여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 내용은 다중 화면지원 개발자 가이드를 참조하세요.

화면 크기 small
normal
large
xlarge
  • small: 저밀도 QVGA 화면과 비슷한 크기의 화면입니다. 작은 화면의 최소 레이아웃 크기는 약 320x426dp 단위입니다. 이 화면의 예시로는 QVGA 저밀도 및 VGA 고밀도가 있습니다.
  • normal: 중밀도 HVGA 화면과 비슷한 크기의 화면입니다. 정상 화면의 최소 레이아웃 크기는 약 320x470dp 단위입니다. 이 화면의 예로는 WQVGA 저밀도, HVGA 중밀도, WVGA 고밀도 등이 있습니다.
  • large: 중밀도 VGA 화면과 비슷한 크기의 화면입니다. 큰 화면의 최소 레이아웃 크기는 약 480x640dp 단위입니다. 이 화면의 예시로는 VGA 및 WVGA 중밀도 화면이 있습니다.
  • xlarge: 일반적인 중밀도 HVGA 화면보다 상당히 큰 화면을 말합니다. 초대형 화면의 최소 레이아웃 크기는 약 720x960dp 단위입니다. 대부분의 경우, 초대형 화면 기기는 주머니에 넣어 다니기에 너무 큽니다. 따라서 태블릿 스타일의 기기일 가능성이 높습니다. API 레벨 9에서 추가되었습니다.

참고: 크기 한정자를 사용하더라도 해당 리소스가 그 크기의 화면 전용이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를 제공하지 않으면, 시스템이 가장 가깝게 일치하는 리소스를 사용합니다.

주의: 모든 리소스가 현재 화면보다 크기 한정자를 사용하는 경우, 시스템은 리소스를 사용하지 않으며 앱은 런타임에 작동이 중단됩니다(예: 모든 레이아웃 리소스에 xlarge 한정자가 태그로 지정되어 있지만 기기는 일반 크기 화면일 경우).

API 레벨 4에서 추가되었습니다.

자세한 정보는 다중 화면 지원을 참조하세요.

screenLayout 구성 필드도 참조하세요. 이 필드는 화면이 소형인지, 일반 크기인지, 대형인지를 나타냅니다.

화면 비율 long
notlong
  • long: WQVGA, WVGA, FWVGA 등의 긴 화면
  • notlong: QVGA, HVGA 및 VGA 등의 길지 않은 화면

API 레벨 4에서 추가되었습니다.

이것은 순전히 화면 비율에만 기초합니다("긴" 화면이 더 넓습니다). 화면 방향과는 관계가 없습니다.

화면이 긴 화면인지 여부를 나타내는 screenLayout도 참조하세요.

원형 화면 round
notround
  • round: 원형 화면(예: 원형 웨어러블 기기)
  • notround: 사각형 화면(예: 전화 또는 태블릿)

API 레벨 23에서 추가되었습니다.

화면이 원형인지 여부를 나타내는 isScreenRound() 구성 메서드도 참조하세요.

넓은 색 공간 widecg
nowidecg
  • {@code widecg}: Display P3, AdobeRGB 등과 같은 넓은 색 공간으로 표시합니다.
  • {@code nowidecg}: sRGB와 같은 좁은 색 공간으로 표시합니다.

API 레벨 26에서 추가되었습니다.

화면이 넓은 색 공간을 가졌는지 나타내는 isScreenWideColorGamut() 구성 메서드도 참조하세요.

HDR(High Dynamic Range) highdr
lowdr
  • {@code highdr}: 높은 동적 범위로 표시합니다.
  • {@code lowdr}: 낮은/표준 동적 범위로 표시합니다.

API 레벨 26에서 추가되었습니다.

화면에 HDR 기능이 있는지 나타내는 isScreenHdr() 구성 메서드도 참조하세요.

화면 방향 port
land
  • port: 기기가 세로 방향(수직)입니다.
  • land: 기기가 가로 방향(수평)입니다.

사용자가 화면을 돌리는 경우 앱 수명 중에 화면 방향이 변경될 수 있습니다. 화면 방향이 런타임에 앱에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

현재 기기 방향을 나타내는 orientation 구성 필드도 참조하세요.

UI 모드 car
desk
television
appliance
watch
vrheadset
  • car: 기기가 차량용 도크에서 표시되고 있습니다.
  • desk: 기기가 데스크용 도크에서 표시되고 있습니다.
  • television: 기기가 텔레비전에서 표시되고 있으며, UI가 큰 화면에 있고 사용자가 여기에서 멀리 떨어져 있는 "텐 풋(ten foot)" 환경을 제공하고 있습니다. 이는 주로 DPAD 또는 기타 비-포인터 상호작용 주변을 가리킵니다.
  • appliance: 기기가 가전 제품 역할을 하고 있으며, 디스플레이 화면이 없습니다.
  • watch: 기기에 디스플레이 화면이 있고 손목에 착용합니다.
  • vrheadset: 기기가 가상현실 헤드셋에서 표시됩니다.

API 레벨 8에서 추가되었고, 텔레비전은 API 13에서, 시계는 API 20에서 추가되었습니다.

기기가 도크에 삽입되거나 제거될 때 앱이 응답하는 방식에 관한 정보는 도킹 상태 및 유형 판별과 모니터링을 읽어보세요.

UI 모드는 사용자가 기기를 도크에 놓는 경우 앱 수명 중에 변경될 수 있습니다. 이러한 모드 중 일부는 UiModeManager를 사용하여 활성화 또는 비활성화할 수 있습니다. 화면 방향이 런타임에 앱에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

야간 모드 night
notnight
  • night: 야간
  • notnight: 주간

API 레벨 8에서 추가되었습니다.

야간 모드가 자동 모드인 상태(기본)로 설정되어 있으면 앱의 수명 중에 모드가 변경될 수 있습니다. 이 경우 하루 중 시간대를 기반으로 변경됩니다. 이 모드는 UiModeManager를 사용하여 활성화 또는 비활성화할 수 있습니다. 화면 방향이 런타임에 앱에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

화면 픽셀 밀도(dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi: 저밀도 화면, 약 120dpi.
  • mdpi: 중밀도(일반적인 HVGA에서) 화면, 약 160dpi.
  • hdpi: 고밀도 화면, 약 240dpi.
  • xhdpi: 초고밀도 화면, 약 320dpi. API 레벨 8에서 추가되었습니다.
  • xxhdpi: 슈퍼 초고밀도 화면, 약 480dpi. API 레벨 16에서 추가되었습니다.
  • xxxhdpi: 울트라 슈퍼 초고밀도 화면 사용(런처 아이콘만 해당, 다중 화면 지원참고 참조), 약 640dpi. API 레벨 18에서 추가되었습니다.
  • nodpi: 기기 밀도에 일치하도록 크기를 조정하지 않을 비트맵 리소스에 사용할 수 있습니다.
  • tvdpi: mdpi와 hdpi 사이 어딘가에 해당되는 화면, 약 213dpi. "기본" 밀도 그룹으로 간주되지 않습니다. 이는 대체로 텔레비전용으로 만들어진 것이므로 대부분의 앱에는 필요하지 않습니다. 대부분의 앱에는 mdpi 및 hdpi 리소스 제공만으로 충분하고 시스템에서 필요에 따라 리소스를 확대/축소합니다. API 레벨 13에서 추가되었습니다.
  • anydpi: 이 한정자는 모든 화면 밀도와 일치하고 다른 한정자보다 우선합니다. 벡터 드로어블에 유용합니다. API 레벨 21에서 추가되었습니다.
  • nnndpi: 표준이 아닌 밀도를 표현하는 데 사용합니다. nnn는 양의 정수 화면 밀도입니다. 대부분의 경우에는 사용해서는 안 됩니다. 표준 밀도 범위를 사용하세요. 현재 업계에서 사용되고 있는 다양한 기기 화면 밀도를 지원하는 부담이 크게 감소합니다.

여섯 가지 기본 밀도의 비율 척도는 3:4:6:8:12:16입니다(tvdpi 밀도는 무시). 그러므로 ldpi의 9x9 비트맵은 mdpi에서 12x12이고, hdpi에서 18x18, xhdpi에서 24x24와 같은 방식으로 적용됩니다.

이미지 리소스가 텔레비전이나 특정 기기에서 제대로 보이지 않는다고 생각해서 tvdpi 리소스를 사용하려 할 경우, 배율은 1.33*mdpi입니다. 예를 들어 mdpi 화면의 100px x 100px 이미지는 tvdpi에서 133px x 133px이 되어야 합니다.

참고: 밀도 한정자를 사용하더라도 해당 리소스가 그 밀도의 화면 전용이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를 제공하지 않으면, 시스템이 가장 가깝게 일치하는 리소스를 사용합니다.

다양한 화질을 처리하는 방법과 Android가 현재 화질에 맞춰 비트맵을 축소하는 방법에 관한 자세한 내용은 다중 화면 지원을 참조하세요.

터치스크린 유형 notouch
finger
  • notouch: 기기에 터치스크린이 없습니다.
  • finger: 기기에 터치 스크린이 있으며 이를 사용자의 손가락을 사용한 방향 지시 상호작용을 통해 쓰도록 되어 있습니다.

기기에서 사용되는 터치 스크린의 유형을 나타내는 touchscreen 구성 필드도 참조하세요.

키보드 가용성 keysexposed
keyshidden
keyssoft
  • keysexposed: 기기에서 키보드를 사용할 수 있습니다. 키보드에 소프트웨어 키보드가 활성화되어 있으면(이럴 가능성이 큽니다), 하드웨어 키보드가 사용자에게 노출되어 있지 않거나 기기에 하드웨어 키보드가 없더라도 이 리소스를 사용할 수 있습니다. 소프트웨어 키보드가 제공되어 있지 않거나 비활성화되어 있는 경우, 하드웨어 키보드가 노출되어 있을 때에만 사용할 수 있습니다.
  • keyshidden: 기기에서 하드웨어 키보드를 사용할 수 있지만 숨겨져 있고 이에 더하여 기기에 소프트웨어 키보드가 활성화되어 있지 않습니다.
  • keyssoft: 기기에 활성화된 소프트웨어 키보드가 있습니다(표시 여부는 무관).

keysexposed 리소스를 제공하지만 keyssoft 리소스는 제공하지 않는다면, 시스템은 소프트웨어 키보드가 활성화되어 있는 동안은 키보드가 보이는지 여부와 관계없이 keysexposed 리소스를 사용합니다.

이는 사용자가 하드웨어 키보드를 여는 경우 앱 수명 중에 변경될 수 있습니다. 화면 방향이 런타임에 앱에 어떤 영향을 미치는지 알아보려면 런타임 변경 처리를 참조하세요.

또한, 구성 필드 hardKeyboardHiddenkeyboardHidden도 참조하세요. 이 필드는 각각 하드웨어 키보드의 가시성과 모든 종류의 키보드(소프트웨어 포함)의 가시성을 나타냅니다.

기본 텍스트 입력 방법 nokeys
qwerty
12key
  • nokeys: 기기에 텍스트 입력을 위한 하드웨어 키가 없습니다.
  • qwerty: 기기에 하드웨어 쿼티 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는 무관).
  • 12key: 기기에 하드웨어 12키 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는 무관).

기본 텍스트 입력 메서드를 사용할 수 있는지 여부를 나타내는 구성 필드 keyboard도 참조하세요.

플랫폼 버전(API 레벨) 예:
v3
v4
v7
등.

기기에서 지원하는 API 레벨입니다. 예를 들어, v1은 API 레벨1용이고(Android 1.0 이상 기기), v4는 API 레벨 4용(Android1.6 이상 기기)입니다. 이 값에 관한 자세한 내용은 Android API 레벨 문서를 참조하세요.

참고: 일부 구성 한정자는 Android1.0 이후부터 추가되었으므로 모든 Android 버전이 모든 한정자를 지원하는 것은 아닙니다. 새로운 한정자를 사용하면 암묵적으로 플랫폼 버전 한정자도 추가하므로 구형 기기가 이를 무시하게 됩니다. 예를 들어 w600dp 한정자를 사용하면 자동으로 v13 한정자를 포함합니다. 사용 가능한 너비 한정자가 API 레벨 13부터 새로 도입되었기 때문입니다. 애초에 문제를 예방하려면 항상 기본 리소스를 한 세트 포함하세요(한정자 없는 리소스 한 세트). 자세한 내용은 리소스와 연관된 최선의 기기 호환성 제공을 참조하세요.

한정자 이름 규칙

다음은 구성 한정자 이름 사용에 관한 규칙입니다.

  • 한 가지 리소스 세트에 여러 개의 한정자를 사용할 수 있으며, 대시로 구분하면 됩니다. 예를 들어 drawable-en-rUS-land는 가로 방향의 US-English 기기에 적용합니다.
  • 한정자는 표 2에 나열된 순서를 따라야 합니다. 예를 들면 다음과 같습니다.
    • 잘못된 배열: drawable-hdpi-port/
    • 맞는 배열: drawable-port-hdpi/
  • 대체 리소스 디렉토리는 중첩될 수 없습니다. 예를 들어 res/drawable/drawable-en/는 있을 수 없습니다.
  • 값은 대소문자를 구분하지 않습니다. 리소스 컴파일러가 처리 전에 디렉토리 이름을 소문자로 바꿔 대소문자를 구분하지 않는 파일 시스템에서 문제를 일으키지 않도록 방지합니다. 이름에 대문자가 있는 것은 오로지 가독성을 향상하기 위해서입니다.
  • 각 한정자 유형에 한 개의 값만 지원됩니다. 예를 들어 스페인과 프랑스에 같은 드로어블 파일을 사용하고자 하는 경우, 디렉토리 이름이 drawable-rES-rFR/이면 안 됩니다. 대신 drawable-rES/drawable-rFR/ 같이 적절한 파일이 포함된 두 개의 리소스 디렉토리가 필요합니다. 다만 양쪽 위치에 같은 파일을 실제로 복제할 필요는 없습니다. 그 대신 리소스에 별칭을 만들면 됩니다. 아래의 별칭 리소스 생성을 참조하세요.

이런 한정자로 이름을 지은 디렉토리에 대체 리소스를 저장하고 나면 Android가 현재 기기 구성에 기초하여 앱에 자동으로 리소스를 적용합니다. 리소스가 요청될 때마다 Android가 요청한 리소스 파일이 들어 있는 대체 리소스 디렉토리를 확인하고, 그런 다음 가장 잘 일치하는 리소스를 찾습니다(아래에서 설명). 특정 기기 구성에 일치하는 대체 리소스가 없는 경우, Android는 상응하는 기본 리소스(구성 한정자를 포함하지 않는 특정 리소스 유형에 대한 리소스 세트)를 사용합니다.

별칭 리소스 생성

어떤 리소스를 하나 이상의 기기 구성에서 사용하고자 하는 경우(그렇지만 이를 기본 리소스를 제공하는 것은 원치 않는 경우), 같은 리소스를 하나 이상의 대체 리소스 디렉토리에 넣지 않아도 됩니다. 대신 기본 리소스 디렉토리에 저장된 리소스에 대해 별칭 역할을 하는 대체 리소스를 만들면 됩니다(경우에 따라).

참고: 모든 리소스가 다른 리소스에 대한 별칭을 생성할 수 있는 메커니즘을 제공하는 것은 아닙니다. 특히, xml/ 디렉토리의 애니메이션, 메뉴, 원시 및 기타 지정되지 않은 리소스는 이 기능을 제공하지 않습니다.

예를 들어 앱 아이콘 icon.png이 있고 서로 다른 로케일에서 이 아이콘의 고유 버전이 필요한 경우가 있습니다. 그러나 English-Canadian과 French-Canadian의 두 로케일은 같은 버전을 사용해야 합니다. English-Canadian과 French-Canadian 양쪽 모두에 대한 리소스 디렉토리에 같은 이미지를 복사해야 한다고 생각할 수 있지만, 실은 그렇지 않습니다. 대신 두 로케일에서 사용하는 이미지를 icon_ca.png(icon.png 이외에 어떤 이름이든 가능)로 저장하고 이를 기본 res/drawable/ 디렉토리에 넣으면 됩니다. 그런 다음 <bitmap> 요소를 사용하여 icon_ca.png리소스를 참조하는 res/drawable-en-rCA/res/drawable-fr-rCA/에서 icon.xml 파일을 생성합니다. 이렇게 하면 PNG 파일 버전 하나와 그것을 가리키는 작은 XML 파일 두 개만 저장할 수 있습니다. (XML 파일 예시는 아래와 같습니다.)

드로어블

기존 드로어블에 별칭을 생성하려면 <drawable> 요소를 사용합니다. 예를 들면 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="icon">@drawable/icon_ca</drawable>
</resources>

파일을 res/values-en-rCA/와 같은 대체 리소스 디렉토리에 drawables.xml로 저장하면, R.drawable.icon으로 참조할 수 있는 리소스로 컴파일됩니다. 그러나 이것은 실제로는 R.drawable.icon_ca 리소스(res/drawable/에 저장됨)의 별칭입니다.

레이아웃

기존 레이아웃에 별칭을 생성하려면 <merge> 안에 싸여있는 <include> 요소를 사용합니다. 예를 들면 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<merge>
    <include layout="@layout/main_ltr"/>
</merge>

파일을 main.xml로 저장하면, R.layout.main으로 참조할 수 있는 리소스로 컴파일됩니다. 그러나 이것은 실제로는 R.layout.main_ltr리소스의 별칭입니다.

문자열 및 기타 단순 값

기존 문자열에 별칭을 생성하려면 원하는 문자열의 리소스 ID를 새 문자열의 값으로 사용하면 됩니다. 예를 들면 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello</string>
    <string name="hi">@string/hello</string>
</resources>

이제 R.string.hi 리소스는 R.string.hello의 별칭입니다.

기타 단순 값도 같은 방식으로 동작합니다. 예를 들면 색상은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="red">#f00</color>
    <color name="highlight">@color/red</color>
</resources>

앱 리소스 액세스

일단 어떤 리소스를 애플리케이션에 제공한 다음에는, 해당 리소스의 리소스 ID를 참조함으로써 이를 적용할 수 있습니다. 모든 리소스 ID는 aapt 도구가 자동으로 생성하는 프로젝트의 R 클래스에서 정의됩니다.

애플리케이션이 컴파일되면 aaptR 클래스를 생성하며, 이 클래스 안에 res/ 디렉토리에 있는 모든 리소스의 리소스 ID가 들어 있습니다. 각 리소스 유형에는 R 하위 클래스가 있고(예: 모든 드로어블 리소스에 대한 R.drawable), 해당 유형의 각 리소스에는 고정된 정수가 있습니다(예: R.drawable.icon). 이 정수가 리소스를 검색하는 데 사용할 수 있는 리소스 ID입니다.

리소스 ID가 R 클래스에서 지정되기는 하지만, 리소스 ID를 찾기 위해 이곳을 볼 필요는 전혀 없습니다. 리소스 ID는 항상 다음과 같이 구성됩니다.

  • 리소스 유형: 각 리소스는 '유형'으로 그룹화됩니다(예: string, drawable, and layout). 다양한 유형에 관한 자세한 내용은 리소스 유형을 참조하세요.
  • 리소스 이름:리소스가 단순 값(예: 문자열 등)일 경우, 확장자를 제외한 파일 이름이나 XML android:name 특성 값 중 하나입니다.

리소스에 액세스하는 방법은 두 가지가 있습니다.

  • 코드 내부에서: R 클래스의 하위 클래스에서 고정된 정수를 사용합니다. 예를 들면 다음과 같습니다.
    R.string.hello

    string은 리소스 유형이고 hello는 리소스 이름입니다. 리소스 ID를 이 형식으로 제공하면 리소스에 액세스할 수 있는 Android API가 많습니다. 코드 내 리소스 액세스를 참조하세요.

  • XML 내부에서: R 클래스에서 정의된 리소스 ID에 상응하기도 하는 특수 XML 구문을 사용합니다. 예를 들면 다음과 같습니다.
    @string/hello

    string은 리소스 유형이고 hello는 리소스 이름입니다. 이 구문은 리소스로 값을 제공할 것으로 예상되는 어느 곳에나 XML 리소스 형태로 사용할 수 있습니다. XML에서 리소스 액세스를 참조하세요.

코드 내 리소스 액세스

리소스 ID를 메서드 매개변수로 전달하면 코드 내 리소스를 사용할 수 있습니다. 예를 들어, ImageView를 설정하여 setImageResource()를 사용하는 res/drawable/myimage.png 리소스를 사용할 수 있습니다.

Kotlin

val imageView = findViewById(R.id.myimageview) as ImageView
imageView.setImageResource(R.drawable.myimage)

Java

ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);

Resources에서 메서드를 사용하는 개별 리소스를 검색할 수도 있으며, 이는 getResources()로 인스턴스를 가져올 수 있습니다.

구문

다음은 코드로 리소스를 참조하는 데 쓰는 구문입니다.

[<package_name>.]R.<resource_type>.<resource_name>
  • <package_name>은 리소스가 위치한 패키지의 이름입니다(자체 패키지의 리소스를 참조할 경우에는 필요하지 않음).
  • <resource_type>은 해당 리소스 유형의 R 하위 클래스입니다.
  • <resource_name>은 확장자가 없는 리소스 파일 이름이거나 XML 요소의 android:name 특성 값입니다(단순 값의 경우).

각 리소스 유형과 참조 방법에 관한 자세한 내용은 리소스 유형을 참조하세요.

사용 사례

리소스 ID 매개변수를 허용하는 메서드가 많이 있고, Resources에서 메서드를 사용하여 리소스를 검색할 수 있습니다. Context.getResources()Resources의 인스턴스를 가져올 수 있습니다.

다음은 코드로 리소스에 액세스한 몇 가지 예시입니다.

Kotlin

// Load a background for the current screen from a drawable resource
window.setBackgroundDrawableResource(R.drawable.my_background_image)

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID
window.setTitle(resources.getText(R.string.main_title))

// Load a custom layout for the current screen
setContentView(R.layout.main_screen)

// Set a slide in animation by getting an Animation from the Resources object
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in))

// Set the text on a TextView object using a resource ID
val msgTextView = findViewById(R.id.msg) as TextView
msgTextView.setText(R.string.hello_message)

Java

// Load a background for the current screen from a drawable resource
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;

// Set the Activity title by getting a string from the Resources object, because
//  this method requires a CharSequence rather than a resource ID
getWindow().setTitle(getResources().getText(R.string.main_title));

// Load a custom layout for the current screen
setContentView(R.layout.main_screen);

// Set a slide in animation by getting an Animation from the Resources object
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
        R.anim.hyperspace_in));

// Set the text on a TextView object using a resource ID
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);

주의: 수동으로 R.java 파일을 수정해서는 안 됩니다. 프로젝트가 컴파일되었을 때 aapt 도구가 생성한 파일이기 때문입니다. 모든 변경 사항은 다음번 컴파일에서 재정의됩니다.

XML에서 리소스 액세스

기존 리소스에 대한 참조를 사용하여 일부 XML 특성과 요소의 값을 정의할 수 있습니다. 이 작업은 레이아웃 파일을 생성할 때 위젯에 문자열과 이미지를 제공하기 위해 자주 하게 됩니다.

예를 들어, 레이아웃에 Button을 추가하면 해당 버튼 텍스트에 문자열 리소스를 사용해야 합니다.

<Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/submit" />

구문

다음은 XML 리소스로 리소스를 참조하는 데 쓰는 구문입니다.

@[<package_name>:]<resource_type>/<resource_name>
  • <package_name>은 리소스가 위치한 패키지의 이름입니다(같은 패키지의 리소스를 참조할 경우에는 필요하지 않음).
  • <resource_type>은 해당 리소스 유형의 R 하위 클래스입니다.
  • <resource_name>은 확장자가 없는 리소스 파일 이름이거나 XML 요소의 android:name 특성 값입니다(단순 값의 경우).

각 리소스 유형과 참조 방법에 관한 자세한 내용은 리소스 유형을 참조하세요.

사용 사례

일부 경우에는 값에 대한 리소스를 반드시 XML로 사용해야 하지만(예: 위젯에 드로어블 이미지를 적용하는 경우), 단순 값을 허용하는 곳이라면 어디서든 XML로 리소스를 사용할 수도 있습니다. 예를 들어, 색상 리소스문자열 리소스를 포함한 다음과 같은 리소스 파일을 가지고 있다고 가정해보겠습니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="opaque_red">#f00</color>
   <string name="hello">Hello!</string>
</resources>

이와 같은 리소스는 다음의 레이아웃 파일에서 텍스트 색상과 텍스트 문자열을 설정하는 데 사용할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@color/opaque_red"
    android:text="@string/hello" />

이 경우, 리소스를 자체 패키지에서 가져왔으므로 리소스 참조에 패키지 이름을 지정하지 않아도 됩니다. 시스템 리소스를 참조하려면 패키지 이름을 포함해야 합니다. 예를 들면 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:textColor="@android:color/secondary_text_dark"
    android:text="@string/hello" />

참고: 항상 문자열 리소스를 사용해야 사용자의 애플리케이션이 다른 언어에 맞게 현지화될 수 있습니다. 대체 리소스(예: 현지화된 문자열) 생성에 관한 자세한 내용은 대체 리소스 제공을 참조하세요. 다른 언어로 애플리케이션을 현지화하기 위한 전체 지침은 현지화를 참조하세요.

XML의 리소스를 사용하여 별명을 생성할 수도 있습니다. 예를 들어, 드로어블 리소스이면서 다른 드로어블 리소스의 별명인 것을 생성할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/other_drawable" />

일견 중복되는 것처럼 들리지만, 대체 리소스를 사용할 때 매우 유용하게 쓰일 수 있습니다. 별칭 리소스 생성에 대해 자세히 알아보세요.

스타일 특성 참조

스타일 특성 리소스는 현재 적용된 테마의 특성 값을 참조할 수 있게 해줍니다. 스타일 특성을 참조하면 하드 코드로 작성된 값을 제공하는 대신에 UI 요소의 외관을 사용자가 지정하여, 현재 테마에서 제공한 표준 변형에 맞추어 스타일링할 수 있습니다. 스타일 특성을 참조하는 것은 기본적으로 "이 특성이 정의한 스타일을 현재 테마로 사용하라"는 말과 같습니다.

스타일 특성을 참조하는 경우, 이름 구문은 일반적인 리소스 형식과 거의 똑같습니다. 다만 앳 기호(@)를 사용하는 대신 물음표(?)를 사용하며, 리소스 유형 부분이 선택 사항이라는 점만 다릅니다. 예:

?[<package_name>:][<resource_type>/]<resource_name>

예컨대 다음은 텍스트 색상을 시스템 테마의 "기본" 텍스트 색상에 일치하도록 설정하기 위해 특성을 참조하는 방법을 나타냅니다.

<EditText id="text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="?android:textColorSecondary"
    android:text="@string/hello_world" />

여기서 android:textColor 특성이 현재 테마에 스타일 특성의 이름을 지정합니다. Android는 이제 android:textColorSecondary 스타일 특성에 적용된 값을 이 위젯의 android:textColor에 대한 값으로 사용합니다. 시스템 리소스 도구는 특성 리소스가 이 컨텍스트에서 예상된다는 것을 알기 때문에 유형(?android:attr/textColorSecondary)을 명시적으로 선언하지 않아도 됩니다. 즉, attr 유형은 배제해도 됩니다.

원본 파일 액세스

흔한 일은 아니지만, 원본 파일과 디렉토리에 액세스해야 하는 경우가 있습니다. 이 경우에는 res/에 파일을 저장하더라도 소용이 없습니다. res/에서 리소스를 읽는 방법은 리소스 ID를 사용하는 것뿐이기 때문입니다. 대신 assets/ 디렉토리에 리소스를 저장할 수 있습니다.

assets/ 디렉토리에 저장된 파일은 리소스 ID가 부여되지 않으므로, 이와 같은 리소스는 R 클래스나 XML 리소스에서 참조할 수 없습니다. 그 대신 일반 파일 시스템처럼 assets/ 디렉토리에 파일을 쿼리하고 AssetManager를 사용하여 원시 데이터를 읽을 수 있습니다.

하지만 원시 데이터(예: 동영상, 오디오 파일)를 읽는 기능만 필요한 경우라면, 파일을 res/raw/ 디렉토리에 저장한 다음 openRawResource()를 사용하여 일련의 바이트 스트림을 읽으면 됩니다.

플랫폼 리소스 액세스

Android에는 스타일, 테마 및 레이아웃 등 여러 가지 표준 리소스가 포함되어 있습니다. 이와 같은 리소스에 액세스하려면 android 패키지 이름으로 리소스 참조를 한정합니다. 예를 들어 Android는 ListAdapter의 목록 항목으로 사용할 수 있는 레이아웃 리소스를 제공합니다.

Kotlin

listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, myarray)

Java

setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));

이 예시에서 simple_list_item_1ListView의 항목에 대해 플랫폼이 정의한 레이아웃 리소스입니다. 목록 항목에 대해 나름의 레이아웃을 만드는 대신 이것을 사용해도 됩니다.

리소스와 연관된 최선의 기기 호환성 제공

앱이 여러 기기 구성을 지원하게 하려면, 언제나 앱이 사용하는 각 유형의 리소스에 기본 리소스를 제공하는 것이 매우 중요합니다.

예를 들어 앱이 여러 언어를 지원할 경우, 항상 언어 및 지역 한정자 없이 values/ 디렉토리(문자열이 저장된 디렉토리)를 포함시켜야 합니다. 그렇게 하지 않고 언어와 지역 한정자가 있는 디렉토리에 모든 문자열을 넣으면, 문자열이 지원하지 않는 언어로 설정된 기기에서 앱을 실행하면 작동이 중단됩니다. 그러나 기본 values/ 리소스를 제공하는 한은 앱이 제대로 실행됩니다(사용자가 이해하지 못하는 언어로라도 작동하므로 아예 앱의 작동이 중단되는 것보다는 낫습니다.)

마찬가지로 화면 방향에 기초하여 여러 가지 레이아웃 리소스를 제공하는 경우, 하나의 방향을 기본값으로 선택해야 합니다. 예를 들어 가로 방향에는 layout-land/로, 세로 방향에는 layout-port/로 레이아웃 리소스를 제공하는 대신 하나를 기본으로 남겨두세요. 가로 방향인 경우 layout/으로 제공하고, 세로 방향인 경우 layout-port/로 제공하는 식으로 하면 됩니다.

앱이 예상치 못한 구성에서 실행될 수 있을 뿐만 아니라 Android의 새 버전에서 이전 버전에서는 지원하지 않는 구성 한정자를 추가할 수도 있으므로, 기본 리소스를 제공하는 것이 중요합니다. 새 리소스 한정자를 사용하지만 Android 이전 버전과 코드 호환성은 유지한 경우, 그 후 Android 이전 버전이 앱을 실행하면 새로운 한정자로 이름을 지정한 리소스를 사용할 수 없게 됩니다. 이때 기본 리소스를 제공하지 않으면 앱 작동이 중단됩니다. 예를 들어 minSdkVersion이 4로 설정되어 있는데 야간 모드(API 레벨 8에서 추가된 night 또는 notnight)를 사용하여 모든 드로어블 리소스를 한정할 경우, API 레벨 4 기기가 드로어블 리소스에 액세스하지 못하고 작동을 중단합니다. 이 경우, notnight를 기본 리소스로 제공하는 것이 좋습니다. 즉, 드로어블 리소스가 drawable/ 또는 drawable-night/이 되도록 해당 한정자를 제외해야 합니다.

그러므로 최선의 기기 호환성을 제공하려면 언제나 앱에서 반드시 제대로 수행해야 하는 리소스에 대해 기본 리소스를 제공하세요. 그런 다음 구성 한정자를 사용하여 특정 기기 구성에 대해 대체 리소스를 생성하면 됩니다.

이 규칙에는 한 가지 예외가 있습니다. 앱의 minSdkVersion이 4 이상이면화면 밀도 한정자로 대체 드로어블 리소스를 제공할 때 기본 드로어블 리소스가 없어도 됩니다. 기본 드로어블 리소스가 없더라도 Android가 대체 화면 화질 중에서 가장 잘 맞는 리소스를 찾고 필요에 따라 비트맵을 축소합니다. 그러나 모든 유형의 기기에서 최상의 경험을 제공하려면, 모든 세 가지 유형의 밀도에 대해 대체 드로어블을 제공해야 합니다.

Android가 가장 잘 일치하는 리소스를 찾는 방법

개발자가 대체를 제공하는 리소스를 요청하면 Android가 현재 기기 구성에 따라 런타임에 어느 대체 리소스를 사용할지 선택합니다. Android가 대체 리소스를 선택하는 방법을 보여주기 위해 다음 드로어블 디렉토리에 같은 이미지의 서로 다른 버전이 들어 있다고 가정하겠습니다.

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

그리고 기기의 구성은 다음과 같습니다.

로케일 = en-GB
화면 방향 = port
화면 픽셀 밀도 = hdpi
터치 스크린 유형 = notouch
기본 텍스트 입력 방법 = 12key

Android는 기기 구성을 이용 가능한 대체 리소스와 비교하여, drawable-en-port에서 드로어블을 선택합니다.

시스템은 다음과 같은 논리에 따라 어느 리소스를 사용할지 결정합니다.

그림 2. Android가 가장 잘 일치하는 리소스를 찾는 방법을 보여주는 흐름도.

  1. 기기 구성과 충돌하는 리소스 파일을 제거합니다.

    drawable-fr-rCA/en-GB 로케일과 충돌하므로 제거되었습니다.

    drawable/
    drawable-en/
    drawable-fr-rCA/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    예외: 화면 픽셀 밀도 한정자 하나만은 충돌을 이유로 제거되지 않습니다. 기기의 화면 밀도가 hdpi라도, 현 시점에서는 모든 화면 밀도가 일치로 간주되므로 drawable-port-ldpi/를 제거하지 않습니다. 자세한 내용은 다중 화면 지원 문서에서 확인하실 수 있습니다.

  2. 목록(표2)에서 (그다음으로) 우선순위가 가장 높은 한정자를 선택합니다. (MCC부터 시작해서 아래로 내려가세요.)
  3. 리소스 디렉토리 중에 이 한정자를 포함한 것이 있나요?
    • 없을 경우, 2단계로 돌아가 다음 한정자를 살펴보세요 (이 예시의 경우 언어 한정자에 도달할 때까지 답은 "없습니다"입니다).
    • 있는 경우, 4단계로 계속 진행합니다.
  4. 이 한정자를 포함하지 않는 리소스 디렉토리는 제외합니다. 이 예시에서는 시스템이 언어 한정자를 포함하지 않는 디렉토리를 모두 제거합니다.
    drawable/
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    예외: 문제의 한정자가 화면 픽셀 밀도라면, Android는 기기 화면 밀도와 가장 가깝게 일치하는 옵션을 선택합니다. 일반적으로 Android는 작은 원본 이미지를 확대하는 것보다 큰 원본 이미지를 축소하는 것을 선호합니다. 다중 화면 지원을 참조하세요.

  5. 뒤로 돌아가 디렉토리가 한 개만 남을 때까지 2, 3, 4단계를 반복합니다. 이 예시에서 일치하는 것이 있는 다음 한정자는 화면 방향입니다. 따라서 화면 방향을 지정하지 않는 리소스는 제거됩니다.
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    

    남은 디렉토리는 drawable-en-port입니다.

이 절차는 요청된 각 리소스에 대해 실행하지만, 시스템이 몇 가지 측면을 추가로 최적화합니다. 예를 들어 시스템이 기기 구성을 확인하고 나서 절대 일치할 가능성이 없는 대체 리소스를 제거합니다. 가령 구성 언어가 영어("en")라면 영어 이외의 다른 언어 한정자로 설정된 리소스 디렉토리는 절대 확인된 리소스 풀에 포함되지 않습니다(언어 한정자가 포함되지 않는 리소스 디렉토리는 여전히 포함됩니다).

화면 크기 한정자에 기초하여 리소스를 선택할 때 시스템은 가장 잘 일치하는 리소스가 없다면 현재 화면보다 작은 화면에 지정된 리소스를 사용합니다(예를 들어 큰 화면은 필요에 따라 일반 크기 화면 리소스를 사용합니다). 그러나 사용 가능한 리소스가 현재 화면보다 더 크다면 시스템은 이를 사용하지 않습니다. 기기 구성과 일치하는 다른 리소스가 없는 경우 앱의 작동 중단됩니다(예를 들어 모든 레이아웃 리소스가 xlarge 한정자로 태깅되어 있지만, 기기가 보통 크기 화면인 경우).

참고: 한정자의 우선순위(표 2 참조)가 기기와 정확하게 일치하는 한정자 수보다 더 중요합니다. 예를 들어 위의 4단계에서 목록의 마지막 선택 항목에 기기와 정확히 일치하는 한정자가 세 개 포함되어 있지만(방향, 터치 스크린유형, 입력 방법), drawable-en에는 일치하는 매개변수가 하나뿐입니다(언어). 다만 언어가 이러한 다른 한정자보다 우선순위가 높기 때문에 drawable-port-notouch-12key는 탈락합니다.