본문 바로가기
Android

[깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 정리 14 - 안드로이드 리소스

by 들풀민들레 2022. 5. 9.

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

본 글은 [깡쌤의 안드로이드 프로그래밍 with 자바 - 2022 - 쌤즈] 의 내용을 발췌한 것입니다.
좀더 자세한 내용은 책 혹은 인강(www.ssamz.com)을 통해 확인해 주세요.

 

 

6.1. 안드로이드 리소스


이 책에서 지금까지는 레이아웃, 이미지, 그리고 문자열 등의 리소스(resource)를 이용해보았는데요.
안드로이드에서 제공하는 리소스는 이 이외에도 많습니다. 안드로이드 프로그램을 작성하면서 리소스를
이용하면 개발 생산성과 유지보수에 도움을 줍니다. 이번 절에서는 values 리소스와 XML 파일 형태의
다양한 리소스를 살펴보겠습니다.


6.1.1. 리소스 종류

 

안드로이드 앱의 리소스들은 모두 res 폴더 하위에 있어야 하며, 개발자가 임의로 폴더를 정의하는 것이
아니라 리소스별 폴더명이 지정되어 있습니다.

  • drawable: 이미지, 이미지와 관련된 XML, 그림을 표현한 XML
  • layout: 화면 UI를 정의한 레이아웃 XML
  • values: 문자열, 색상, 크기 등 여러 가지 값
  • menu: 액티비티의 메뉴를 구성하기 위한 XML
  • xml: 특정 폴더가 지정되어 있지 않은 기타 XML
  • anim: 애니메이션을 위한 XML
  • raw: 바이트 단위로 직접 이용되는 이진 파일
  • mipmap: 앱 아이콘 이미지


이처럼 리소스 폴더명은 고정되어 있어서 개발자가 임의로 정의할 수 없으며, 리소스 폴더 하위에
서브 폴더를 작성할 수도 없습니다. 그리고 각 폴더에 리소스 파일을 추가하는 순간, 추가한 리소스를
식별하기 위한 int 형 변수가 R.java 파일에 추가됩니다. 이때 파일명을 변수명으로 사용하므로 리소스
파일명은 자바 명명규칙을 위배할 수 없습니다. 또한, 리소스 파일명에는 대문자를 사용할 수 없습니다.


6.1.2. 다양한 리소스 활용


크기 리소스와 색상 리소스
안드로이드 리소스 중 문자열, 배열, 색상, 크기 등 흔히 값이라고 표현되는 리소스는 values 폴더
하위에 위치합니다. 이러한 리소스들은 다른 리소스와 다르게 파일명으로 직접 식별되는 것이 아니라,
각 XML 파일의 태그 이름값으로 식별되어 사용됩니다. values 하위에는 문자열, 색상, 스타일, 배열
정보, 크기 정보 등이 들어갈 수 있는데, 권장 파일명은 다음과 같습니다.

 

  • strings.xml: 문자열 리소스 여러 개를 담는 파일. 파일 내에 <string> 태그로 각 리소스 등록
  • colors.xml: 색상 리소스 여러 개를 담는 파일. 파일 내에 <color> 태그로 각 리소스 등록
  • styles.xml: 스타일을 여러 개 담는 파일. 파일 내에 <style> 태그로 각 리소스 등록
  • arrays.xml: 배열 리소스 여러 개를 담는 파일. 파일 내에 <string-array>, <integer-array> 태그로 각 리소스 등록
  • dimens.xml: 크기 리소스를 담는 파일. 파일 내의 <dimen> 태그로 각 리소스 등록

크기 값을 등록하려면 dimens.xml 파일 내에 <dimen> 태그를 이용하여 등록할 수 있습니다.

 

<resources>
<dimen name="my_margin">16dp</dimen>
<dimen name="my_padding">16dp</dimen>
</resources>

이렇게 등록한 크기 리소스는 R.java 파일에 등록된 dimen 변수를 이용하여 사용합니다. 다음의
코드는 xml 파일 내에서 속성값으로 dimen 리소스를 사용한 것이며, 이를 자바 코드에서 이용하려면
R.dimen.my_padding처럼 사용하면 됩니다.

 

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:padding="@dimen/my_padding"
android:layout_margin="@dimen/my_margin" />

색상 리소스는 values 밑에 colors.xml 파일 내에 <color> 태그를 이용하여 등록합니다.

 

<resources>
<color name="my_background">#FFFF0000</color>
<color name="my_textColor">#FF00FFFF</color>
</resources>

이렇게 등록한 색상 리소스는 R.java 파일에 등록된 color 변수를 이용하여 사용합니다. 다음의
코드는 xml 파일 내에서 속성값으로 color 리소스를 사용한 것이며, 이를 자바 코드에서 이용하려면
R.color.background처럼 사용하면 됩니다.

 

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:background="@color/my_background"
android:textColor="@color/my_textColor" />

 

스타일 리소스
안드로이드에서 액티비티를 이용하여 화면을 구성할 때 주로 레이아웃 XML 파일을 이용하여
구성하는데, 여러 뷰를 레이아웃 XML에 명시하다 보면 같은 속성이 계속 반복되는 경우가 있습니다.
예로 들면 앱 개발 시 TextView를 워낙 많이 이용하는데, 모든 TextView에 textSize, textColor,
textStyle이 같은 값으로 적용되어야 하는 경우입니다. 이처럼 같은 속성이 계속 중복될 때 스타일
리소스를 이용하면 중복을 피할 수 있습니다.
스타일 리소스는 여러 속성을 하나의 스타일로 묶어 필요한 곳에 적용하기 위해 사용됩니다. values
폴더의 styles.xml 파일을 이용합니다. 다음의 코드는 3개의 속성을 묶는 "myStyle"이라는 이름의
새로운 스타일을 정의하였습니다.

 

<style name="myStyle">
<item name="android:textColor">#FF0000FF</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
</style>

정의한 스타일을 레이아웃 XML 파일에서 style 속성을 이용하여 지정해주면 3개의 속성이 한꺼번에
적용된 효과가 납니다.

 

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First"
style="@style/myStyle"
/>

스타일을 정의할 때 다른 스타일을 상속받아 재정의하는 방법도 제공합니다.

 

<style name="myStyle">
<item name="android:textColor">#FF0000FF</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
</style>
<style name="mySubStyle" parent="myStyle">
<item name="android:textStyle">italic</item>
</style>

"myStyle"을 하나 정의하고, 그 아래에 "mySubStyle"을 정의하였는데, mySubStyle은 parent
속성을 이용하여 myStyle을 상속받아 정의하였습니다. 이렇게 하면 mySubStyle에는 myStyle의
내용이 그대로 계승되며, mySubStyle에 새로운 내용을 추가하거나 기존의 것을 바꾸어 사용할 수
있습니다. 위의 코드대로 설명하면 mySubStyle에는 textColor, textSize, textStyle을 정의하였는데,
textColor, textSize는 myStyle 내용을 그대로 계승하고, textStyle만 italic으로 바꾼 예입니다.

 

테마 리소스
위에서 살펴본 스타일은 뷰를 위한 스타일입니다. 그런데 액티비티 전체 혹은 앱 전체를 위한
스타일이 있습니다. 이를 흔히 테마(theme)라고 부르는데요.
안드로이드 모듈을 만들면, 기본으로 테마가 등록된 themes.xml 파일이 생성됩니다. 파일명은 themes.xml이지만 <style> 태그로 정의합니다.

 


테마 설정의 대표적인 예로 툴바(toolbar)를 생각해 볼 수 있습니다.
툴바와 관련된 자세한 이야기는 이후에 하고, 여기서는 툴바의 스타일만 생각해 보겠습니다.

 

그림 6-2는 액티비티를 띄웠을 때의 기본 화면입니다. 액티비티 전체 영역에서 윗부분이 툴바입니다.
툴바의 색상이 보라색 계열이 나왔고 문자열이 흰색으로 표현되었습니다. 이 색상이 적용된 것은 기본
테마가 적용되었기 때문입니다. 모듈을 만들 때 기본으로 만들어지는 themes.xml 파일을 보면 다음과
같은 설정이 있습니다.

 

<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>

라이브러리에서 제공하는 테마를 상속받아 "Theme.AndroidLab"라는 이름의 스타일이 하나
정의되어 있고, 이 테마가 액티비티에 적용되어 있습니다. 테마 적용은 뷰를 위한 스타일이 아니므로
레이아웃 XML 파일에 적용하는 게 아니라, 액티비티가 등록되는 AndroidManifest.xml에
설정합니다.

 

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AndroidLab">
<!--중략-->
</application>

액티비티의 <application> 태그에 theme 설정이 themes.xml에 선언한 "Theme.AndroidLab"로
되어 있어서, 애플리케이션의 모든 액티비티의 툴바 색상이 Theme.AndroidLab에서 지정한 색상으로
나오게 됩니다.

 

화면을 여러 개의 영역으로 구분해 색상을 부여하기 위해, 영역마다 이름이 지정되어 있습니다.
colorPrimary와 colorSecondary는 앱의 브랜드를 표현하기 위한 색상입니다. colorPrimary는
툴바와 버튼의 백그라운드 색상으로 적용되며 colorSecondary는 체크박스, 라디오버튼, 스위치 등의
활성 상태 색상입니다. 그리고 statusBarColor는 상태바의 백그라운드 색상으로 사용됩니다.
또한 colorOnPrimary와 colorOnSecondary는 colorPrimary와 colorSecondary가 적용되는 곳의
포그라운드 색상으로 적용됩니다. 그리고 colorPrimaryVariant와 colorSecondaryVariant는 그림자
색상으로 사용합니다.
해당 값을 변경하는 것만으로 액티비티의 색상을 지정할 수 있습니다. 다음은 기본으로 제공되는
Theme.AndroidLab의 색상만 바꾼 예입니다.

 

<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">#FF0000</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorSecondary">#00FF00</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">#FFFFFF</item>
<item name="android:statusBarColor" tools:targetApi="l">#0000FF</item>
<!-- Customize your theme here. -->
</style>

이렇게 정의한 테마를 <application> 태그에 적용하면 애플리케이션 내의 모든 액티비티에 같은 테마가
적용됩니다. 애플리케이션 내에 액티비티가 여러 개 있을 때, 이 중 하나의 액티비티에만 적용해야 하는
테마도 있겠지요. 이럴 때는 테마를 <activity> 태그에 설정하면 됩니다.

 

<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.AndroidLab">

테마를 액티비티에 설정하면 툴바의 색상 값뿐 아니라 툴바 자체가 화면에 안 나오게 할 수도 있습니다.
NoActionBar를 상속받아 아래처럼 설정하면 테마가 적용된 액티비티의 툴바 영역이 안 보이게
됩니다.

 

<style name="Theme.AndroidLab" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- 생략 -->
</style>

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.