[android]03. 드로어블

목차

  1. 드로어블
  2. 상태 드로어블
  3. 쉐이프 드로어블



1. 드로어블

드로어블(Drawable)

정적 이미지를 앱에 표시해야 할 때 Drawable 클래스와 subclass를 사용하여 도형과 이미지를 그릴 수 있습니다. Drawable은 그릴 수 있는 항목의 일반 추상화입니다. 다양한 subclass는 특정 이미지 시나리오에 유용하며 이 클래스를 확장하여 고유한 방식으로 동작하는 자체 드로어블 객체를 정의할 수 있습니다.

클래스 생성자를 사용하는 방법 이외에 다음 두 방법을 사용하여 Drawable을 정의하고 인스턴스화할 수 있습니다.

  • 프로젝트에 저장된 이미지 리소스(비트맵 파일)를 확장합니다.
  • 드로어블 속성을 정의하는 XML 리소스를 확장합니다.

다양한 subclass가 있습니다.

  • 비트맵 드로어블(BitmapDrawable)은 이미지 파일을 보여줄 때
  • 상태 드로어블(StateListDrawable)은 상태별 다른 그래픽을 참조할 때
  • 전환 드로어블(TrasitionDrawable)은 두 개의 드로어블 간에 바뀌도록 만들 때
  • 도형 드로어블(ShapeDrawable)은 도형 모양을 정의할 때
  • 인셋 드로어블(InsetDrawable)은 뷰가 뷰의 실제 범위보다 작은 백그라운드가 필요할 때
  • 클립 드로어블(ClipDrawable)은 다른 드로어블을 클리핑할 때
  • 크기 드로어블(ScaleDrawable)은 다른 드로어블의 크기를 바꿀 때
  • 그 외에 다양한 drawable subclass가 존재합니다.

공식 문서 - Drawable

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 파일을 만듭니다.

0302


다음과 같이 두 개의 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 파일로 설정합니다.

0303


확인해봅시다.

0304
기본 상태
0305
누르고 있을 때



쉐이프 드로어블(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>

실제로 적용된 모습을 확인해봅시다.

0306
차례대로 중첩 쉐이프 적용, gradient 적용


출처: 공식 문서 - Shape Drawable