목차
1. 드로어블
드로어블(Drawable)
정적 이미지를 앱에 표시해야 할 때 Drawable 클래스와 subclass를 사용하여 도형과 이미지를 그릴 수 있습니다. Drawable은 그릴 수 있는 항목의 일반 추상화입니다. 다양한 subclass는 특정 이미지 시나리오에 유용하며 이 클래스를 확장하여 고유한 방식으로 동작하는 자체 드로어블 객체를 정의할 수 있습니다.
클래스 생성자를 사용하는 방법 이외에 다음 두 방법을 사용하여 Drawable을 정의하고 인스턴스화할 수 있습니다.
- 프로젝트에 저장된 이미지 리소스(비트맵 파일)를 확장합니다.
- 드로어블 속성을 정의하는 XML 리소스를 확장합니다.
다양한 subclass가 있습니다.
- 비트맵 드로어블(BitmapDrawable)은 이미지 파일을 보여줄 때
- 상태 드로어블(StateListDrawable)은 상태별 다른 그래픽을 참조할 때
- 전환 드로어블(TrasitionDrawable)은 두 개의 드로어블 간에 바뀌도록 만들 때
- 도형 드로어블(ShapeDrawable)은 도형 모양을 정의할 때
- 인셋 드로어블(InsetDrawable)은 뷰가 뷰의 실제 범위보다 작은 백그라운드가 필요할 때
- 클립 드로어블(ClipDrawable)은 다른 드로어블을 클리핑할 때
- 크기 드로어블(ScaleDrawable)은 다른 드로어블의 크기를 바꿀 때
- 그 외에 다양한 drawable subclass가 존재합니다.
2. 상태 드로어블 (StateList Drawable)
다수의 그래픽 이미지를 단일 Drawable에 할당하고 표시되는 항목을 상태에 따라 교체할 수 있습니다. <selector>요소를 사용하여 XML 파일로 정의할 수 있습니다. 각 그래픽은 <selector> 요소 내에 있는 <item> 요소로 표현됩니다. <item>은 드로어블에 대한 그래픽으로 사용되는 상태를 설명합니다.
파일 위치
res/drawable/filename.xml
리소스 참조
Java: R.drawable.filename
XML: @[package:]drawable/filename
상태 드로어블 syntax
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize=["true" | "false"]
android:dither=["true" | "false"]
android:variablePadding=["true" | "false"] >
<item
android:drawable="@[package:]drawable/drawable_resource"
android:state_pressed=["true" | "false"]
android:state_focused=["true" | "false"]
android:state_hovered=["true" | "false"]
android:state_selected=["true" | "false"]
android:state_checkable=["true" | "false"]
android:state_checked=["true" | "false"]
android:state_enabled=["true" | "false"]
android:state_activated=["true" | "false"]
android:state_window_focused=["true" | "false"] />
</selector>
selector
필수. 이는 루트 요소여야 합니다. 하나 이상의 <item> 요소를 포함합니다.
selector 특성
- xmlns:android
문자열. 필수. XML 네임스페이스를 정의합니다. 이는 “http://schemas.android.com/apk/res/android”여야 합니다. - android:constantSize
부울. 드로어블의 보고된 내부 크기가 상태가 변경되어도 동일하게 유지되는 경우(크기가 모든 상태의 최댓값인 경우) “true”이고, 크기가 현재 상태에 따라 달라지는 경우 “false”입니다. 기본값은 false입니다. - android:dither
부울. 비트맵에 화면과 동일한 픽셀 구성이 없는 경우(예: RGB 565 화면에 ARGB 8888 비트맵 설정) 비트맵에 대한 디더링을 활성화하려면 “true”이고, 디더링을 비활성화하려면 “false”입니다. 기본값은 true입니다. - android:variablePadding
부울. 드로어블의 패딩이 선택된 현재 상태에 따라 변경되어야 하는 경우 “true”이고, 패딩이 (모든 상태의 최대 패딩을 기준으로) 동일하게 유지되어야 하는 경우 “false”입니다. 이 기능을 활성화하려면 상태가 변경될 때 실행 중인 레이아웃을 처리해야 합니다. 이는 보통 지원되지 않습니다. 기본값은 false입니다.
item
특성으로 규정된 대로, 특정 상태 동안 사용할 드로어블을 정의합니다. <selector> 요소의 하위 요소여야 합니다.
item 특성
- android:drawable
드로어블 리소스. 필수. 드로어블 리소스에 대한 참조입니다. - android:state_pressed
부울. 객체를 누를 때(예: 버튼을 터치하거나 클릭할 때) 이 항목을 사용하려는 경우 “true”이고, 누르지 않은 기본 상태에서 이 항목을 사용하려는 경우 “false”입니다. - android:state_focused
부울. 객체에 입력 포커스가 있을 때(예: 사용자가 텍스트 입력을 선택할 때) 이 항목을 사용하려는 경우 “true”이고, 누르지 않은 기본 상태에서 이 항목을 사용하려는 경우 “false”입니다. -
android:state_hovered
부울. 커서가 객체를 가리킬 때 이 항목을 사용하려는 경우 “true”이고, 누르지 않은 기본 상태에서 이 항목을 사용하려는 경우 “false”입니다. 대체로, 이 드로어블은 “포커스가 있는” 상태에 사용되는 것과 동일한 드로어블일 수 있습니다. API 레벨 14에서 추가되었습니다. -
android:state_selected
부울. 방향 컨트롤을 사용하여 탐색할 때(예: 방향 패드(d-pad)를 사용하여 목록을 탐색할 때) 객체가 현재 사용자가 선택한 항목일 때 이 항목을 사용하려는 경우 “true”이고, 객체가 선택되지 않았을 때 이 항목을 사용하려는 경우 “false”입니다. 포커스(android:state_focused)가 충분하지 않은 경우(예: 목록 뷰에 포커스가 있고 뷰 내부의 항목이 방향 패드를 사용하여 선택된 경우) 선택된 상태가 사용됩니다. - android:state_checkable
부울. 객체가 선택 가능할 때 이 항목을 사용하려는 경우 “true”이고, 객체가 선택 가능하지 않을 때 이 항목을 사용하려는 경우 “false”입니다. (객체가 선택 가능한 위젯과 선택 불가능한 위젯 간을 전환할 수 있는 경우에만 유용합니다.) - android:state_checked
부울. 객체가 선택되었을 때 이 항목을 사용하려는 경우 “true”이고, 객체가 선택 취소되었을 때 이 항목을 사용하려는 경우 “false”입니다. - android:state_enabled
부울. 객체가 활성화되었을 때(터치/클릭 이벤트를 수신 가능한 경우) 이 항목을 사용하려는 경우 “true”이고, 객체가 비활성화되었을 때 이 항목을 사용하려는 경우 “false”입니다. -
android:state_activated
부울.객체가 영구적인 선택 항목으로 활성화되었을 때(예: 영구적인 탐색 뷰에서 이전에 선택한 목록 항목을 “강조표시”하려는 경우) 이 항목을 사용하려는 경우 “true”이고, 객체가 활성화되지 않았을 때 이 항목을 사용하려는 경우 “false”입니다. API 레벨 11에서 추가되었습니다. - android:state_window_focused
부울. 애플리케이션 창에 포커스가 있을 때(애플리케이션이 전경에 있는 경우) 이 항목을 사용하려는 경우 “true”이고, 애플리케이션 창에 포커스가 없을 때(예: 알림 창이 내려져 있거나 대화상자가 표시되어 있는 경우) 이 항목을 사용하려는 경우 “false”입니다.
상태가 변경될 때마다 상태 목록이 맨 위부터 맨 아래까지 통과되고 현재 상태와 일치하는 첫 번째 항목이 사용됩니다. 이때 “최상의 일치” 항목이 아니라, 최소 상태 기준을 충족하는 첫 번째 항목을 기준으로 항목이 선택됩니다.
출처: 공식 문서 - StateList Drawable
상태 드로어블 예시
버튼을 누를 때 이미지가 변하는 예를 들어 봅시다.
res/drawable 폴더에 이미지 파일을 넣습니다.
xml 파일에 상태 드로어블을 규정합시다. res/drawable 폴더에 우클릭 후 새로운 xml 파일을 만듭니다.
다음과 같이 두 개의 item을 정의합니다.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/marguerite_729510_640" />
<item android:drawable="@drawable/roses_1566792_640"/>
</selector>
버튼의 background를 새로 만든 xml 파일로 설정합니다.
확인해봅시다.
쉐이프 드로어블(Shape Drawable)
XML에 정의된 일반 도형을 그릴 수 있습니다.
파일 위치
res/drawable/filename.xml
리소스 참조
Java: R.drawable.filename
XML: @[package:]drawable/filename
쉐이프 드로어블 syntax
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="float"
android:centerY="float"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>
shape
셰이프 드로어블입니다. 이는 루트 요소여야 합니다.
shape 특성
- xmlns:android
문자열. 필수. XML 네임스페이스를 정의합니다. 이는 “http://schemas.android.com/apk/res/android”여야 합니다. - android:shape
키워드. 셰이프의 유형을 정의합니다. 유효한 값은 다음과 같습니다.
값 | 설명 |
---|---|
rectangle | 포함하는 뷰를 채우는 사각형. 기본 셰이프입니다. |
oval | 포함하는 뷰의 치수에 맞는 타원형 셰이프. |
ling | 포함하는 뷰의 너비에 걸쳐 있는 가로선. 이 셰이프를 사용하려면 |
ring | 고리형 셰이프. |
corners
셰이프에 대해 둥근 모서리를 생성합니다. 셰이프가 사각형인 경우에만 적용됩니다.
corners 특성
- android:radius
치수. 모든 모서리의 반경으로, 치수 값이나 치수 리소스로 지정됩니다. 이 값은 각 모서리에 대해 다음 특성으로 재정의됩니다. - android:topLeftRadius
치수. 왼쪽 상단 모서리의 반경으로, 치수 값이나 치수 리소스로 지정됩니다. - android:topRightRadius
치수. 오른쪽 상단 모서리의 반경으로, 치수 값이나 치수 리소스로 지정됩니다. - android:bottomLeftRadius
치수. 왼쪽 하단 모서리의 반경으로, 치수 값이나 치수 리소스로 지정됩니다. - android:bottomRightRadius
치수. 오른쪽 하단 모서리의 반경으로, 치수 값이나 치수 리소스로 지정됩니다.
gradient
셰이프에 대한 그라데이션 색상을 지정합니다.
gradient 특성
- android:angle
정수. 그라데이션의 각도(단위: 도)입니다. 0은 왼쪽에서 오른쪽으로 진행되며, 90은 하단에서 상단으로 진행됩니다. 45의 배수여야 합니다. 기본값은 0입니다. - android:centerX
부동 소수점 수. 그라데이션의 중심에 대한 상대적인 X 위치입니다(0 ~ 1.0). - android:centerY
부동 소수점 수. 그라데이션의 중심에 대한 상대적인 Y 위치입니다(0 ~ 1.0). - android:centerColor
색상. 시작 색상과 끝 색상 사이에 오는 색상(선택 항목)으로, 16진수 값이나 색상 리소스로 지정됩니다. - android:endColor
색상. 끝 색상으로, 16진수 값이나 색상 리소스로 지정됩니다. - android:gradientRadius
부동 소수점 수. 그라데이션의 반경입니다. android:type=”radial”인 경우에만 적용됩니다. - android:startColor
색상. 시작 색상으로, 16진수 값이나 색상 리소스로 지정됩니다. - android:type
키워드. 적용할 그라데이션 패턴의 유형입니다. 유효한 값은 다음과 같습니다.
값 | 설명 |
---|---|
linear | 선형 그라데이션. 이는 기본값입니다 |
radial | 원형 그라데이션. 시작 색상은 가운데 색상입니다. |
sweep | 스위핑 라인 그라데이션. |
- android:useLevel
부울. LevelListDrawable로 사용되는 경우 “true”입니다.
padding
포함하는 뷰 요소에 적용할 패딩입니다(이는 셰이프가 아니라 뷰 콘텐츠의 위치를 패딩함).
padding 특성
- android:left 치수. 왼쪽 패딩으로, 치수 값이나 치수 리소스로 지정됩니다.
- android:top 치수. 상단 패딩으로, 치수 값이나 치수 리소스로 지정됩니다.
- android:right 치수. 오른쪽 패딩으로, 치수 값이나 치수 리소스로 지정됩니다.
- android:bottom 치수. 하단 패딩으로, 치수 값이나 치수 리소스로 지정됩니다.
size
셰이프의 크기입니다.
size 특성
- android:height 치수. 셰이프의 높이로, 치수 값이나 치수 리소스로 지정됩니다.
- android:width 치수. 셰이프의 너비로, 치수 값이나 치수 리소스로 지정됩니다.
solid
셰이프를 채울 단색입니다.
solid 특성
- android:
색상. 셰이프에 적용할 색상으로, 16진수 값이나 색상 리소스로 지정됩니다.
stroke
셰이프에 대한 스트로크 선입니다.
stroke 특성
- android:width
치수. 선의 두께로, 치수 값이나 치수 리소스로 지정됩니다. - android:color
색상. 선의 색상으로, 16진수 값이나 색상 리소스로 지정됩니다. - android:dashGap
치수. 점선 사이의 거리로, 치수 값이나 치수 리소스로 지정됩니다. android:dashWidth가 설정된 경우에만 유효합니다. - android:dashWidth
치수. 각 점선의 크기로, 치수 값이나 치수 리소스로 지정됩니다. android:dashGap이 설정된 경우에만 유효합니다.
쉐이프 드로어블 예시
상태 드로어블 예시와 마찬가지로 res/drawable 폴더에 xml 파일을 생성하고 원하는 설정을 입력합니다.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#BE55DA" />
<solid android:color="#0000000" />
</shape>
</item>
<item android:top="1dp" android:bottom="1dp" android:right="1dp" android:left="1dp">
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#BE55DA" />
<solid android:color="#0000000" />
</shape>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#7288DB"
android:centerColor="#3250B4"
android:endColor="#254097"
android:angle="90"
android:centerY="0.5"/>
<corners
android:radius="2dp"/>
</shape>
실제로 적용된 모습을 확인해봅시다.