드로어블 (Drawable)
드로어블(Drawable)은 뷰에 설정할 수 있는 객체이며 그래픽으로 그릴 수 있습니다.
그래픽이라고 하면 흔히 떠올리는 것이 선이나 원을 선으로 그려주는 것인데요, 이런 작업은 보통 소스 코드에서 하게 됩니다.
하지만 소스 코드가 아닌 XML로 그래픽이 어떻게 그려질지 정의할 수 있다면 좀 더 편리하게 사용할 수 있을 겁니다.
드로어블은 소스 코드에서 만들 수도 있고 XML에서 정의할 수도 있는데 XML로 만들어 사용하는 경우가 많습니다.
드로어블 XML 파일은 /res/drawable 폴더 안에 넣어서 마치 이미지처럼 뷰의 배경으로 설정될 수 있습니다.
드로어블에는 이미지 파일을 보여줄 때 사용하는 비트맵 드로어블(BitmapDrawable), 상태별로 다른 그래픽을 참조할 수 있는 상태 드로어블(StateListDrawable), 두 개의 드로어블 간에 바뀌도록 만들 수 있는 전환 드로어블(TransitionDrawable), 색상과 그러데이션을 포함하여 도형 모양을 정의할 수 있는 쉐이프 드로어블(ShapeDrawable) 등이 있습니다.
지정한 거리만큼 안쪽으로 들어오도록 만들 수 있는 인셋 드로어블(InsetDrawable)은 뷰가 뷰의 실제 범위보다 작은 백그라운드가 필요 할 때 유용하게 사용됩니다.
다른 드로어블을 클리핑하는 클립 드로어블(ClipDrawable)은 진행률 표시 줄과 같은 항목을 구현하는 데 많이 사용됩니다.
그 외로 다른 드로어블의 크기를 바꿀 수 있는 스케일 드로어블(ScaleDrawable)도 있죠.
다양한 기능의 드로어블이 있지만 그중에서 앱을 만들 때 가장 많이 사용하는 드로어블이 상태 드로어블과 쉐이프 드로어블입니다.
상태 드로어블
상태 드로어블은 뷰의 상태에 따라 뷰에 보여줄 그래픽을 다르게 지정할 수 있도록 합니다.
/res/drawable 폴더 안에 새로운 XML 파일을 만들면 최상위 태그는 <selector>가 됩니다.
그 안에 <item> 태그를 넣을 수 있으며 drawable 속성에는 이미지나 다른 그래픽을 설정하여 화면에 보이도록 할 수 있습니다.
state_ 로 시작하는 속성은 상태를 나타내는데 예를 들어 state_pressed 속성은 눌린 상태를 의미하고 state_focused는 포커스를 받은 상태를 의미합니다.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/ic_thumb_up_selected" />
<item android:drawable="@drawable/ic_thumb_up" />
</selector>
상태 속성이 지정되지 않은 <item> 태그에는 drawable 속성에 ic_thumb_up 이미지가 설정되어 있으므로 디폴트 이미지로 보이게 됩니다.
state_pressed 속성이 설정된 <item> 태그에는 ic_thumb_up_selected 이미지가 설정되어 있으며 이 이미지는 뷰가 눌렸을 때 보이게 됩니다.
이렇게 만든 XML 파일은 뷰의 background 속성으로 설정될 수 있습니다.
/res/drawable 폴더 안에 thumb_up.xml 이라는 이름의 파일을 만들었다면 다음과 같이 버튼의 배경으로 설정할 수 있습니다.
<Button
android:id="@+id/button"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/thumb_up"
/>
생각해보기
- 소스 코드로 드로어블을 만드는 것보다 XML로 드로어블을 만들어 사용하면 얼마나 더 편리해지는 걸까요?
- XML로 드로어블을 만들고 레이아웃의 배경으로 설정하면 카드 모양의 배경을 만들 수 있을까요?
참고 자료
comment
수강완료.
최신버전 사용중인데 backgroundTint로 인해 버튼 색상이 고정되는 현상이 발생했고, 버튼 안에 아래 코드 추가하여 정상작동 됐습니다:)
app:backgroundTint="?android:attr/panelBackground"
app:backgroundTintMode="add"
아래는 버튼 전체 코드입니다.
<Button
android:id="@+id/button"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/thumb_up"
app:backgroundTint="?android:attr/panelBackground"
app:backgroundTintMode="add" />
사진 차이인지 버전차이인지는 모르겠지만 버튼의 background에 사진을 넣었을때 그림이 안나오고 그냥 파란 화면만 나오네요 ㅠ
감사핣니다 :)!
: xml 파일로 만들어서 사용하면 재사용 할 수 있음 + 백그라운드에 파일 설정만 해주면 되서 편함
카드 모양이 어떤 모양인지 잘 모르겠지만, 적적히 xml 파일을 사용하면 만들 수 있을 것 같다
수강 완료.
thumb_up 을 Button으로 객체를 만들어 줄수도 있지만 imageView로 만들어 줄수도 있는거로 아는데 선호하시는게 왜 Button이신지 궁금합니다. (요지: 어떤 이점 때문인지??)
소스코드로 드로어블을 어떻게 만드는지 잘 이해가 되지 않는데, xml로 드로어블을 만들어둔다면 같은 기능과 그래픽이 필요할 때 백그라운드에 바로 xml만 추가하면 되서 편리하려나 하고 생각했습니다.
카드모양의 배경이 무슨 의민지는 잘 모르겠지만 레이아웃 background에 버튼에 추가했더 xml파일을 넣으니 디폴트그래픽은 당연히 들어가서 배경을 넣을 수 있다고 생각했습니다
추가로, 눌러도 이미지는 변하지않더군요, 레이아웃뷰에는 press값을 넘기는 기능이 없어서 그럴까 하고 생각했었습니다.
1. XML을 잘 다루는 만큼 편리해진다고 봅니다.
2. 물론 가능하겠죠
: 자바로 예제와 같은 화면을 설정한다고 하면 onClicked 관련 메소드를 작성하고, 이미지를 하나하나 설정해 주어야 하는데 xml로 만들면 훨씬 용이합니다. 화면이 바뀌는 것, 화면에 관련된 것은 xml 을 이용하는 것이 편리합니다.
: 제가 실제로 레이아웃에 같은 drawable을 적용해봤는데, pressed 해도 동작하지 않았습니다ㅠㅠ 왜 인지는 아직 파악하지 못했습니다. 검색해보니 레이아웃은 background에 xml 파일 설정 > java에서 클릭 리스너 설정을 해주면 가능한 것 같습니다.
1.더 간단해질 것 같다.
2.할 수 있다.
1. 소스 코드로 드로어블을 만드는 것보다 XML로 드로어블을 만들어 사용하면 얼마나 더 편리해지는 걸까요?
직접 버튼에 이벤트 핸들러를 사용하지 않아도 간단하게 코드를 써서 기능을 동작 할 수 있기 때문에 시간 소모, 코드 양이 줄어들 수 있을 것 같습니다.
2. XML로 드로어블을 만들고 레이아웃의 배경으로 설정하면 카드 모양의 배경을 만들 수 있을까요?
버튼에 백그라운드를 설정하는 것 처럼 역시 레이아웃 드로어블을 만들어 백그라운드로 적용하면 충분히 만들 수 있을 것 같습니다.
친절하게 설명해주신대로
drawable 폴더 아래에 thumb_up_test1.xml이라는 파일을 만들고
이렇게 코드를 입력한후에
activity_main.xml의 ImageView의 background속성을 thumb_up_test1으로 설정하였는데
좋아요 버튼을 아무리 눌러도 동작이 바뀌지를 않습니다.
원인이 무엇인지 알 수 있을까요?
부탁드립니다!
1. 소스 코드로 드로어블을 만들려면 여러가지 로직이 필요한데, XML는 기능을 제공하기 때문에 편리하다.
2. 만들 수 있을 것 같다.
drawble에 xml파일만들었는데 텍스트만 뜨고, 디자인으론 전환이 안되는데 어떻게 하는거죠 ㅜㅜ 최신버전인데
생각해보기
1. 하나의 XML 드로어블로 가능모양의 여러개 버튼을 효율적으로 관리할 수 있어 편리합니다.
2.버튼이 아닌, 레이아웃 배경도 XML 드로어블로 관리하면 편리하겠네요~
⭐️생각해보기⭐️
1. Java 코드에서 전혀 작성할 필요 없이 xml에서 처리가 가능해집니다.
2. 네 모양을 지정하는 xml을 적절히 활용한다면 가능해보입니다.
비공개 글입니다.
생각해보기
1. XML로 드로어블을 만듦으로써 뷰에 이벤트를 직접 지정해주지 않아도 되어 편의성이 크게 증가하는 것 같습니다. 실제로 했던 생각은 아마 Event를 주어 If문으로 해결할 것이라고 생각했는데 훨씬 간단한 방법이 있네요
2. "카드 모양"이라는게 무슨 의미인지 잘 이해가 되지 않네요..
selector 에서 item 설정시에 순서에 영향받는 것 같아요!
저는 state_pressed 가 밑에 내려가니까 적용이 안되네요 ㅠㅠ 안되시는 분들 참고하세용