CH Park
by CH Park

Categories

  • Android Application

Tags

  • Android
  • Android Studio
  • Application
  • drawable


드로어블(Drawable)

  • 드로어블은 뷰의 상태에 따라 그래픽이나 이미지가 선택적으로 보이게 해줌. 일반적인 뷰의 background 속성만으로는 조작에 따라 반응하여 변하는 버튼이나 이미지를 만들 수가 없음.
  • 드로어블은 뷰에 설정할 수 있는 객체이며 그 위에 그래픽을 그릴 수 있음.
  • 드로어블은 xml파일로, /app/res/drawable 폴더에 저장.
  • 종류
    • 비트맵 드로어블(BitmapDrawable): 이미지 파일을 보여줄 때 사용. 비트맵 그래픽 파일(png, jpg, gif 등)을 사용하여 생성.
    • 상태 드로어블(StateDrawable): 상태별로 다른 비트맵 그래픽을 참조.
    • 전환 드로어블(TransitionDrawable): 두 개의 드로어블을 서로 전환할 수 있음.
    • 셰이프 드로어블(ShapeDrawable): 색상과 그러데이션을 포함하여 도형 모양을 정의할 수 있음.
    • 인셋 드로어블(InsetDrawable): 지정된 거리만큼 다른 드로어블을 들어서 보여줄 수 있음.
    • 클립 드로어블(ClipDrawable): 레벨 값을 기준으로 다른 드로어블을 클리핑할 수 있음.
    • 스케일 드로어블(ScaleDrawable): 레벨 값을 기준으로 다른 드로어블의 크기를 변경할 수 있음.


상태 드로어블(StateDrawable)

<!--[android_drawable.xml]-->

<?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/gengar2" />

    <item android:drawable="@drawable/gengar1"/>

</selector>
<!--[activity_main.xml]-->

    <Button
        android:id="@+id/button3"
        android:layout_width="200dp"
        android:layout_height="120dp"
        android:adjustViewBounds="true"
        android:background="@drawable/android_drawable"
        android:backgroundTintMode="src_atop"
        android:scaleType="fitCenter"
        app:backgroundTint="#00FFFFFF"
        app:backgroundTintMode="add"
        app:layout_constraintBottom_toTopOf="@+id/imageButton2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />
  • 최상위 태그인 selector 태그 안에는 item 태그를 넣을 수 있으며, item 태그의 drawable 속성에 이미지나 그래픽을 설정하여 화면에 출력 가능.
  • state_로 시작하는 속성은 상태를 나타내고, 코드 상의 state_pressed는 눌린 상태를 의미.
  • 기본적으로 state가 설정되어 있지 않은 item이 화면에 출력되며, state_pressed가 되면 해당 item이 화면에 출력됨.
  • 위의 드로어블을 씌우고 싶은 버튼의 background 속성에 위 xml파일을 지정하면 배경으로서 버튼의 그래픽이 됨.

일반 버튼에 background가 드러나지 않는 이유: 일반 버튼의 경우 background 속성을 설정한 것만으로는 배경이 드러나지 않는데, 이는 최신 버전의 Android Studio가 backgroundTint 속성에 default 값을 넣어두었기 때문. 따라서 backgroundTint를 투명하게 설정하고 backgroundTintMode를 add로 설정하면 원래 설정해뒀던 background가 드러남.
backgroundTint에 대해서는 보다 자세한 조사가 필요함


이미지버튼으로 배경 지정: 일반 버튼의 background 속성으로 이미지를 입히는 과정을 이미지버튼을 이용하여 간단히 구현할 수 있는데, 이미지버튼의 경우 버튼이 아닌 ImageView를 상속하기에 버튼과는 조금 다른 코드를 보인다.

<!--[activity_main.xml]-->

   <ImageButton
        android:id="@+id/imageButton2"
        android:layout_width="200dp"
        android:layout_height="120dp"
        android:adjustViewBounds="true"
        android:background="@android:color/transparent"
        android:scaleType="fitCenter"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button3"
        app:srcCompat="@drawable/android_drawable" />


셰이프 드로어블(ShapeDrawable)

<!--[rect_drawable.xml]-->

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <size android:width="200dp" android:height="120dp"/>
    <stroke android:width="1dp" android:color="#0000ff"/>
    <solid android:color="#aaddff"/>
    <padding android:bottom="1dp"/>

</shape>
  • 최상위 태그는 ‘selector’ 태그에서 ‘shape’ 태그로 변경했으며, ‘shape’라는 속성에서 ‘rectangle’ 모양 지정.
    • ‘size’ 속성은 도형의 크기, ‘stroke’ 태그는 테두리 선의 속성, ‘solid’는 도형 안쪽을 채울 때, ‘padding’은 테두리 안쪽 공간을 띄우고 싶을 때 사용하는 태그.
<!--[back_drawable.xml]-->

<?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="#254095"
        android:angle="90"
        android:centerY="0.5"/>

    <corners android:radius="2dp"/>

</shape>
  • ‘shape’ 태그 안에 ‘gradient’ 태그를 넣으면 그라데이션을 만들 수 있음.
  • ‘startColor’에는 시작 부분의 색상, ‘centerColor’에는 중간 부분, ‘endColor’에는 끝 부분의 색상을 지정할 수 있음.
  • ‘angle’ 속성은 그라데이션이 시작되는 위치를 지정하게 되는데, 따로 지정하지 않으면 위에서부터 시작점이 되고, 0이나 360일 때는 왼쪽, 90일 때는 아래쪽, 180일 때는 오른쪽, 270일 때는 위쪽에서 시작된다. 단, 0이거나 90의 배수가 아닌 값은 유효하지 않다.
  • ‘centerY’ 속성은 그라데이션의 중간 위치를 지정하게 된다. 0에서 1 사이의 값으로 지정되어 0.5는 Y축의 정중앙을 그라데이션 중앙으로 한다.
  • ‘corners’ 태그의 ‘radius’ 속성은 테두리 부분의 모서리 모양을 원에 가깝게 하는, 즉 모서리의 완만함을 설정하는 속성이다. 값이 커질수록 더 둥글둥글해진다.
<!--[border_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="#00000000"/>
            <size android:width="200dp" android:height="100dp"/>
        </shape>
    </item>

    <item android:top="1dp" android:bottom="1dp" android:left="1dp" android:right="1dp">
        <shape android:shape="rectangle">
            <stroke android:width="1dp" android:color="#FF55DA"/>
            <solid android:color="#00000000"/>
        </shape>
    </item>

</layer-list>
  • ‘layer-list’ 태그를 사용하면 여러 개의 그래픽을 하나의 XML 파일에 중첩하여 넣을 수 있음.
  • 위 코드는 두 개의 rectangle을 중첩하여 표현하는 코드이다. 각 rectangle은 서로 다른 색의 테두리를 가지고 있으며, 아래의 rectangle은 전 방향에 대해 1dp씩의 간격을 두고 있다. 따라서 아래의 rectangle의 경계선을 기준으로 위의 rectangle이 전 방향에 대해 1dp씩의 간격을 두고 그려졌음을 확인할 수 있다.
  • ‘layer-list’ 내의 ‘item’들에게 각각 크기를 지정하더라도 그 중 가장 큰 크기가 ‘layer-list’의 크기로서 화면에 나타남을 볼 수 있었다. 이는 모든 ‘item’들의 기준이 되는 ‘layer-list’의 크기를 하나로 정하기 위한 방법으로 생각된다.