[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