본문 바로가기
깡샘 코틀린

09-2 리소스 조건 설정

by 농농씨 2023. 6. 23.

리소스 조건 설정이란?

어떤 리소스를 특정 환경에서만 적용되도록 설정하는 것을 말한다. 

왜 필요한가?

만약 기기에 앱을 설치하면 바탕화면에 앱을 실행하는 실행 아이콘이 나온다. 앱을 개발할 때 이 실행 아이콘에 해당하는 이미지를 리소스 디렉터리 mipmap에 준비한다. 그런데 만약 이미지를 하나만 준비했는데 기기마다 화면 크기가 달라지면 선명하게 나오지 않는 문제가 발생한다.

그러므로 개발자는 아이콘이 선명하게 나오게 하기 위해 이미지를 기기에 맞는 크기로 여러 장 준비한다. 보통 5장 정도.

 

그런데 문제는 이미지를 어느 기기의 크기에 적용하는지를 어떻게 결정할 것인가이다. 

이 작업을 코드에서도 할 수 있지만 프로그램이 복잡해지고 리소스를 사용하는 목적과도 맞지 않는다.

이때 리소스 조건을 이용한다. 즉, 리소스를 각 기기의 크기에 맞게 적용하는 작업을 코드에서 하지 않고 리소스 조건으로 지정하여 자동으로 환경에 맞게 적용한다. 

 

리소스 조건을 이용하려면 우선 아이콘의 파일명을 똑같이 지정해야 한다. 모두 ic_launcher.png라는 파일명으로 만들면 R 파일에는 식별자가 하나만 생성된다. 그러므로 코드에서는 각 리소스를 구분할 필요 없이 R.mipmap.ic_launcher라고 지정할 수 있다. 그런데 이렇게 하면 파일명이 중복되는 문제가 발생하는데 이때 디렉터리를 구분하여 해결한다. 즉, 이름이 같은 파일을 하나의 디렉터리가 아니라 mipmap-mdpi, mipmap-hdpi처럼 각각의 디렉터리에 담는다.(mipmap은 앱 실행 아이콘 리소스, hdpi와, mdpi는 기기 종류)

이때 리소스 디렉터리 이름에서 붙임표(-) 뒤의 단어가 리소스의 조건이다. 즉, 이 디렉터리의 리소스가 어느 때에 적용되어야 하는지를 명시하는 조건이다. 예를 들어 mipmap-mdpi 디렉터리는 mdpi 조건을 추가했으므로 mdpi 기기일 때만 플랫폼이 알아서 적용해준다. 

// 리소스 디렉터리명 조건
mipmap-mdpi/ic_launcher.png
mipmap-hdpi/ic_launcher.png
mipmap-xhdpi/ic_launcher.png
mipmap-xxhdpi/ic_launcher.png
mipmap-xxxhdpi/ic_launcher.png
// 기기에 맞는 리소스가 적용됨

결국 기기에 따른 이미지 선택은 리소스 디렉터리명에 이를 명시함으로써 해결할 수 있다.

그런데 실행 아이콘의 디렉터리 조건은 개발자가 신경쓰지 않아도 앱을 만들 때 플랫폼이 알아서 res디렉터리 아래에 mipmap 디렉터리를 여러개 만든다. 아무튼 알아서 해준다.

 

지금까지 mipmap 디렉터리의 실행 아이콘을 예로 들어 리소스 조건을 어떻게 설정하는지 설명했다. 그런데 다른 리소스 디렉터리에도 붙임표(-)를 추가하여 디렉터리명에 조건을 명시하고 각 조건에 맞는 상황에 리소스가 적용되도록 할 수 있다.

언어 및 지역, 이용 가능한 너비, 화면 비율, 야간모드 등을 리소스조건으로 지정할 수 있다.

그런데 이 조건을 어느 리소스 디렉터리에 적용할지는 개발자의 선택이다. 예를들어 언어 조건은 values 디렉터리에 적용하여 values-ko-rKR로, drawable 디렉터리에 적용하여 drawable 디렉터리에 적용하여 drawable-ko-rKR로 사용해도 된다.

또한 이 조건을 디렉터리에 명시할 때 하나의 디렉터리에 여러 조건을 지정해도 된다. 예를 들어 drawable-ko-rKR-xhdpi처럼 drawable 디렉터리에 언어 조건과 밀도 조건을 함께 지정할 수 있다. 이때 주의할 점은 조건의 순서를 지켜야 한다는 것이다. 책에 표가 있는데, 그 표의 순서대로 나열해야한다. 즉, 언어 조건과 밀도 조건을 함께 지정하려면 언어 조건 다음에 밀도 조건이 와야 한다.

 

 

화면 회전에 대응하기

리소스 조건을 이용해 화면 회전에 대응하는 UI를 만들 수 있다. 가로와 세로 방향일 때 출력할 레이아웃 XML 파일을 각각 준비해야 한다. 그런데 어느 방향에서 어떤 XML 파일을 출력할지를 지정해야한다. 이또한 코드로 구현할 수도 있찌만 리소스 조건으로 설정하여 처리하면 더 편리하다.

 

우선 레이아웃 XML 파일을 다음과 같이 2개 만든다. 파일명은 모두 activity_main2.xml이다.

// 세로 방향 레이아웃 XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"> // 세로로 레이아웃
    <ImageView
    	android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:src="@drawable/image1" />
    <ImageView
    	android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:src="@drawable/image2" />
</LinearLayout>
// 가로 방향 레이아웃 XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"> // 가로 레이아웃
    <ImageView
    	android:layout_width="wrap_content" // width, height 속성이 세로레이아웃 파일이랑 반대임
        android:layout_height="0dp"
        android:layout_weight="1"
        android:src="@drawable/image1" />
    <ImageView
    	android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:src="@drawable/image2" />
</LinearLayout>

여기서 중요한 점은 두 파일의 이름이 같다는 점이다. 그리고 리소스 디렉터리명에 조건을 명시해 각각의 파일을 layout 디렉터리에 저장한다.

세로 방향일 때 적용할 activity_main2.xml 은 layout 디렉터리에 저장하고, 가로 방향일 때 적용할 activity_main2.xml 파일은 layout-land 디렉터리에 저장했다 치자. layout 디렉터리에 있는 파일은 디렉터리명에 특정한 조건을 명시하지 않았으므로 기본값, 즉 세로 방향일 떄 적용된다. 

 

 

국제 언어 제공하기

글로벌 서비스를 제공하는 앱이라면 리소스 문자열을 각국 언어로 제공해야 한다. 안드로이드에서는 이 부분도 리소스 조건 설정으로 처리한다. strings.xml 파일에 <string> 태그로 문자열 리소스를 작성하는데, 이 파일을 여러 개 만들어서 각 언어에 맞는 리소스 문자열을 담고 어느 XML 파일을 적용해야 하는지를 리소스 디렉터리명으로 지정하면 된다.

 

다음은 똑같은 내용을 영어와 한국어로 문자열 리소스를 만든 예이다.

// 영어 문자열 리소스 예
<resources>
	<string name="app_name">Test9</string> // values 디렉터리의 리소스라서 파일명이 아닌 
    			// <string> 태그의 name 값으로 문자열 호출함
    <string name="intro">Hello</string>
</resources>
// 한국어 문자열 리소스 예
<resources>
	<string name="app_name">테스트9</string>
    <string name="intro">안녕하세요</string>
</resources>

문자열 리소스는 values 디렉터리의 리소스이므로 식별자는 파일명이 아니라 <string> 태그의 name 값이다. 따라서 각 파일에 문자열을 등록할 때 name 값은 똑같아야 한다. 이 두 파일을 리소스 조건을 명시한 각각의 디렉터리에 만들면 된다.

파일을 보면 strings.xml 파일이 두개 생기는데 한국어가 등록된 파일은 values-ko-rKR 디렉터리에 있따. 이렇게 하는것만으로도 사용자 기기의 지역 설정이 한국이면 이 파일이 적용된다.

영어 문자열이 등록된 string.xml 파일은 특별한 조건 없이 values 디렉터리에 있으므로 기본값이 되어 조건에 맞는 디렉터리 파일이 없을 때 기본으로 적용된다. 물론 영미권 사용자에게만 서비스하겠다면 values-en 으로 디렉터리명을 지정해도 된다.

 

 

 

'깡샘 코틀린' 카테고리의 다른 글

10-1 API 레벨 호환성 고려하기  (2) 2023.06.24
09-3 폰 크기의 호환성  (0) 2023.06.23
09-1 리소스의 종류와 특징  (0) 2023.06.23
08-2 뷰 이벤트  (0) 2023.06.23
08-1 터치와 키 이벤트  (0) 2023.06.22