[Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린] 리소스 활용하기
안드로이드 앱 개발에서 리소스를 효과적으로 활용하는 방법을 정리했다. 리소스는 앱 리소스와 플랫폼 리소스로 나뉘며, 레이아웃, 이미지, 실행 아이콘, 값, 색상, 글꼴 리소스 등 다양한 종류가 있다. 리소스 조건 설정을 통해 특정 환경에서만 적용되도록 설정할 수 있으며, 화면 회전과 국제 언어 지원에도 대응할 수 있다. 또한, 안드로이드 폰의 다양한 크기에 호환성을 고려하여 논리적인 단위로 크기를 지정하고, 기기의 크기 정보를 가져와 직접 조정할 수 있다.
Jul 26, 2024
🌼리소스의 종류와 특징
- 리소스는 앱 리소스와 플랫폼 리소스로 나뉜다.
💡앱 리소스 사용하기
- 리소스란 정적인 자원이다. 정적인 콘텐츠는 코드에 작성하지 않고 분리해서 외부 파일로 만들어 이용할 수 있다.
- 앱 리소스란 개발자가 직접 추가한 리소스다.
- 모듈을 만들면 기본으로 디렉터리 4개가 만들어지지만 리소스 파일의 종류는 더 많다.
디렉터리명 | 리소스 종류 |
animotor | 속성 애니메이션 XML |
anim | 트윈 애니메이션 XML |
color | 색상 상태 목록 정의 XML |
drawable | 이미지 리소스 |
mipmap | 앱 실행 아이콘 리소스 |
layout | 레이아웃 XML |
menu | 메뉴 구성 XML |
raw | 워닛 형태로 이용되는 리소스 파일 |
values | 단순 값으로 이용되는 리소스 |
xml | 특정 디렉터리가 정의되지 않은 나머지 XML 파일 |
font | 글꼴 리소스 |
- res 디렉터리 아래에 개발자가 임의로 이름을 붙인 디렉터리를 만들 수 없고 하위 디렉터리를 추가할 수 없다. 또한 리소스 파일명은 values레 추가하는 파일을 제외하고는 모두 자바의 이름 작성 규칙을 지켜야 하며 알파벳 대문자를 사용할 수 없다.
레이아웃 리소스
는layout 디렉터리
에 저장한다.- 화면을 구성하는 레이아웃 XMl 파일이다.
이미지 리소스
는drawable 디렉터리
에 저장한다.- 이미지는 PNG, JPG, GIF, WEBP, XML로 작성된 이미지다.
- XML 이미지를 만들 때는 다음 태그로 표현한다.
태그 | 설명 |
<shape> | 도형을 의미하며 android:shape=”rectangle”처럼 shape 속성을이용해 도형의 타입을 지정. shape 값은 rectangle, oval, line, ring 중에서 선택. |
<corners> | 둥근 모서리를 그리는 데 사용. shape 값이 rectangle일 때만 적용 |
<gradient> | 그라데이션 색상 지정 |
<size> | 도형의 크기 지정 |
<solid> | 도형의 색상 지정 |
<stroke> | 도형의 윤곽선 지정 |
실행 아이콘 리소스
는mipmap 디렉터리
에 저장한다.- 앱을 기기에 설치하면 나타나는 실행 아이콘의 이미지 리소스다.
값 리소스
는values 디렉터리
에 저장된다.- 문자열, 색상, 크기, 스타일, 배열 등의 값을 XMl로 저장할 수 있다.
- values 디렉터리의 리소스 파일은 파일명이 R인 파일에 식별자로 등록되지 않고 리소스 파일에 값을 지정한 태그의 name 속성값이 등록된다.
- 따라서 파일명은 개발자가 자유롭게 정할 수 있고 대문자를 사용할 수도 있다.
// 문자열 리소스 등록 <resources> <string name="app_name">Test9</string> <string name="txt_data1">Hello</string> <string name="txt_data2">World</string> </resources> // XML에서 문자열 리소스 사용 <TextView (...생략...) android:text="@string/txt/data1"/> // 코드에서 문자열 리소스 사용 binding.textView.text = getString(R.string.txt_data2) // 색상 리소스 등록 <resources> <color name="txt_color">#FFFF00</color> <color name="txt_bg_color">#FF0000</color> </resources> // 크기 리소스 등록 <resources> <dimen name="txt_size">20sp</dimen> </resources> // XML에서 색상과 크기 리소스 사용 <TextView (...생략...) android:textColor="@color/txt_color" android:background="@color/txt_bg_color" android:textSize="@dimen/txt_size"/> // 코드에서 색상과 크기 리소스 사용 binding.textView.text = getString(R.string.txt_data2) binding.textView.setTextColor(ResourcesCompat.getColor(resources, R.color.txt_color, null)) binding.textView.textSize = resources.getDimension(R.dimen.txt_size) // 스타일 등록 <resources> <style name="MyTextStyle"> <item name="android:textSize">@dimen/txt_size</item> <item name="android:textColor">@color/txt_color</item> </style> <style name="MyTextStyleSub" parent="MyTextStyle"> <item name="android:textColor">#00FF00</item> <item name="android:background">@color/txt_bg_color</item> </style> </resources> // 스타일 리소스 사용 <TextView (...생략...) style="@style/MyTextStyleSub" (...생략...)/>
색상 리소스
는color 디렉터리
에 저장한다.values
디렉터리에 만드는 리소스 파일에서<color>
태그로 등록할 수도 있지만, 해당 리소스는 색상 하나를 리소스에 등록하겠다는 의미다. 반면에color 디렉터리
의 리소스는 특정 뷰의 상태를 표현하고 그 상태에 적용되는 색상을 등록할 때 사용한다.
// 색상 리소스 등록 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="#ffff0000"/> <item android:state_focused="true" android:color="#ff0000ff"/> <item android:color="#ff000000"/> </selector> //색상 리소스 사용 <Button (...생략...) android:textColor="@color/button_text" />
글꼴 리소스
는font 디렉터리
를 사용한다.- TTF나 OTF 파일을 저장한 후 글꼴을 적용할 뷰에서 이용하면 된다.
💡플랫폼 리소스 사용하기
- 안드로이드 플랫폼이 제공하는 리소스를 활용할 수 있다.
- 안드로이드 스튜디오의 프로제그 탐색 창에서 보기 옵션을
[Packages]
로 설정한 후[Libraries]
항목을 살펴보면 확인할 수 있다.
- 플랫폼 리소스도 R파일에 등록된 식별자로 이용할 수 있다.
// 코드에서 플랫폼 리소스 사용 binding.imageView.setImageDrawable(ResourcesCompat.getDrawable(resources, android.R.drawable.alert_dark_frame, null)) binding.textView.text=getString(android.R.string.emptyPhoneNumber) // XML에서 플랫폼 리소스 사용 <ImageView (...생략...) android:src="@android:drawable/alert_dark_frame"/> <TextView (...생략...) android:src="@android:string/emptyPhoneNumber"/>
기초 리소스 같은 경우 플랫폼에서 미리 준비해 놓을 수 있으므로 개발할 때 필요한 리소스가 플랫폼 리소스에 있는지 먼저 찾아보는 것이 좋다.ㄴ
🌼리소스 조건 설정
💡리소스 조건 설정이란
- 리소스 조건 설정이란 어떤 리소스를 특정 환경에서만 적용되도록 설정하는 것이다.
- 예를 들어 개발자가 실행 아이콘에 사용할 이미지를 하나만 준비했는데, 기기마다 화면 크기가 달라지면 선명하게 나오지 않는 문제가 발생한다.
- 따라서 보통 앱을 개발할 때는 각 크기별로 이미지를 5개씩 준비한다.
- 리소스 조건을 이용하려면 아이콘의 파일명을 똑같이 지정해야 한다.
- 그 후
mipmap-mdpi/ic_launcher.png
와 같이 조건을 명시해서 사용한다. - 리소스 디렉터리명에 지정할 수 있는 조건은 다음과 같다.
- 조건을 디렉터리에 명시할 때 하나의 디렉터리에 여러 조건을 지정해도 되지만, 조건의 순서는 위와 같은 순서를 지켜야 한다.
화면 밀도 | 크기 |
XXXHDPI | 192 x 192 |
XXHDPI | 144 x 144 |
XHDPI | 96 x 96 |
HDPI | 72 x 72 |
MDPI | 48 x 48 |
조건 | 예시 |
MCC 및 MNC | mcc310
mcc310-mnc004 |
언어 및 지역 | en
ko-kr |
레이아웃 방향 | Idrtl
Idltr |
더 작은 쪽 | sw320dp |
이용 가능한 너비 | w720dp |
이용 가능한 높이 | h720dp |
화면 크기 | small, normal, large, xlarge |
화면 비율 | long, notlong |
원형 화면 | round, notround |
화면 방향 | port, land |
UI 모드 | car, desk, television, application, watch, vrheadset |
야간 모드 | night, notnight |
화면 픽셀 밀도 | ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi, nodpi, tvdpi, anydpi, nnndpi |
터치 스크린 유형 | notouch, finger |
키보드 가용성 | keysexposed, keyshidden, keyssoft |
기본 텍스트 입력방법 | nokeys, qwerty, 12key |
탐색 키 가용성 | navexposed, navhidden |
기본 비터치 탐색방법 | nanav, dpad, trackball, wheel |
플랫폼 버전 | v21 |
💡화면 회전에 대응하기
- 리소스 조건을 이용해 화면 회전에 대응하는 UI를 만들 수 있다. 화면 회전에 대응하려면 가로와 세로 방향일 때 출력할 레이아웃 XML 파일을 각각 준비해야 한다.
- 이 경우 어떤 방향에서 어떤 XML 파일을 출력할지를 리소스 조건으로 설정하여 처리한다.
- 파일명은 모두 같아야 한다.
화면이 회전하면 서비스에 문제가 생기는 게임 앱의 경우 AndroidManifest.xml 파일에 설정하는 것으로 화면을 고정할 수 있다.
하지만 데이터 위주로 서비스하는 앱이라면 가로 방향과 세로 방향을 사용자가 선택할 수 있게 해야 한다.
💡국제 언어 제공하기
- 글로벌 서비스를 제공하는 앱이라면 리소스 문자열을 각국 언어로 제공해야 한다.
- 문자열 리소스는 values 디렉터리의 리소스이므로 식별자는 파일명이 아니라
<string>
태그의name
값이 된다.
🌼폰 크기의 호환성
- 안드로이드 폰은 다양한 크기로 출시된다. 따라서 폰 크기의 호환성을 안드로이드 시스템에서, 또는 개발자가 고려해야 하는 부분이 존재한다.
💡논리적인 단위 알아보기
- 안드로이드 시스템은 다음과 같이 기기의 크기를 구분하여 콘텐츠의 크기를 늘리거나 줄여서 출력한다.
크기 | 설명 | 배율 |
ldpi | ~120dpi | 0.75 |
mdpi | ~160dpi | 1.0 |
hdpi | ~240dpi | 1.5 |
xhdpi | ~320dpi | 2.0 |
xxhdpi | ~480dpi | 3.0 |
xxxhdpi | ~640dpi | 4.0 |
- 안드로이드에서 앱을 개발할 때 크기 지정에 사용할 수 있는 단위는 다음과 같다.
dp
: 스크린의 물리적 밀도에 기반을 둔 단위sp
: dp와 유사하며 글꼴 크기에 적용tp
: 스크린 크기의 1/72을 1pt로 함px
: 픽셀mm
: 밀리미터in
: 인치
- 위 표에 따르면 xxxhdpi의 폰은 개발자가 지정한 크기보다 3배 정도 크게 출력된다. 따라서 콘텐츠의 크기는 될 수 있으면 논리적인 단위로 지정하여 시스템의 도움을 받는 편이 좋다.
💡화면 정보 가져오기
- 개발자가 직접 코드에서 크기 호환성을 조정할 수도 있다. 이 경우 기기의 크기 정보를 가져와야 한다.
- API 레벨 30버전부터는
DisplayMetrics
가 아닌WindowMetrics
를 이용해야 한다.
// 기기의 가로, 세로 크기 가져오기 // Build.VERSION.SDK_INT: 앱이 실행되는 기기의 버전 // Build.VERSION_CODES.R: 안드로이드 11버전(API 레벨 30) if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R{ val windowMetrics: WindowMetrics = windowManager.currentWindowMetrics binding.textView.text = "width : ${windowMetrics.bounds.width()}, height : ${windowMetrics.bounds.height()}" }else{ val display = windowManager.defaultDisplay val displayMetrics = DisplayMetrics() display?.getRealMetrics(displayMetrics) binding.textView.text = "width : ${displayMetrics.widthPixels}, height : ${displayMetrics.heightPixels}" }
🏁결론
안드로이드 앱 개발에서 리소스를 효과적으로 활용하는 방법을 정리했다. 리소스는 앱 리소스와 플랫폼 리소스로 나뉘며, 레이아웃, 이미지, 실행 아이콘, 값, 색상, 글꼴 리소스 등 다양한 종류가 있다. 리소스 조건 설정을 통해 특정 환경에서만 적용되도록 설정할 수 있으며, 화면 회전과 국제 언어 지원에도 대응할 수 있다. 또한, 안드로이드 폰의 다양한 크기에 호환성을 고려하여 논리적인 단위로 크기를 지정하고, 기기의 크기 정보를 가져와 직접 조정할 수 있다.
Share article