layered
9. 드로어블(Drawable) 본문
메모는 개인적으로 느낀 부분을 아무렇게나 적은 것이어서 오류가 있을 수 있다!
개념
보통 뷰에 이미지를 넣을 때에는 background라는 속성을 사용하게 된다.
하지만 만약 좋아요를 눌렀을 때 하트가 칠해지는 것처럼, 어떤 이벤트가 발생할 때 이미지에 변화를 주고 싶다면 어떻게 해야 할까?
이때 드로어블을 사용하게 된다.
드로어블은 뷰에 설정할 수 있는 객체로, 그 위에 그래픽을 그릴 수 있다.
상태에 따라 그래픽이나 이미지가 선택적으로 보이게 할 수도 있다.
따라서 이미지 같은 것을 그냥 바로 /res/drawble에 넣는 게 아니라 xml로 만들어서 넣게 된다.
A Drawable is a general abstraction for "something that can be drawn."
안드로이드 드로어블 문서의 첫줄인데, 추상적이지만 확실한 정의인 것 같다.
그릴 수 있는 것에 대한 일반적인 추상화.
뷰를 상속하는 것은 아니기 때문에 뷰처럼 이벤트를 처리하거나 사용자와 상호작용 할 수는 없다.
메모
낯선 개념이라 조금 추상적이지만 이미지를 객체화해서 사용하자는 것 같다. 단순히 이미지 리소스로 사용하는 것과 객체로 다루는 것은 다르기 때문이다.
음... 자바에서 객체란 상태와 동작을 가지고 있으니까, 정지된 리소스가 아니라 동적인 객체로 더 다채롭게 사용하자는 느낌.
이건 개인적이지만 뷰에서 이미지를 지정하는 background는 그냥 속성 중 하나일 뿐이어서 이미지보다는 그 뷰 자체에 집중하게 되는데, 객체로 만들면 그 이미지만의 고유한 객체가 되는 것이니까 드로어블이라는 게 있는 것 같다.
스폰지밥 이미지가 들어간 "버튼"
스폰지밥 이미지 객체
이런 느낌(?)
상태 드로어블(StateListDrawable)
뷰의 상태에 따라 보여줄 그래픽을 다르게 지정할 수 있다.
drawable 폴더에서 우클릭을 하면 드로어블 리소스 파일을 생성할 수 있다!
이렇게 xml 파일을 만들게 되면 <selector> 태그로 둘러싸인 코드 부분을 볼 수 있다.
넣고자 하는 이미지를 <item> 태그로 감싸서 지정하면 된다.
상태는 state_ 속성으로 설정하는데, 지금은 버튼에 넣을 드로어블을 만들 것이므로 state_pressed를 선택한다.
코드를 다 작성하고 나면 버튼의 background 속성에 드로어블 파일을 넣어 주면 된다.
태그는 <item> 하나뿐인데 그 안에 상태에 관련된 속성들이 많다. state_pressed라든가 state_checked 같은 것들!
속성들의 이름이 대부분 직관적이어서 딱히 정리하지 않아도 될 것 같다.
메모
처음에는 드로어블의 상태와 버튼이 별개인 줄 알았는데, 버튼을 텍스트뷰로 바꿔 보니 하트가 안 채워졌다.
우리가 버튼을 누르면 내부적으로는 pressed 상태가 되고 드로어블에서는 그 상태를 참조하는 형태로 작동하는 것 같다!
background를 설정할 때 @drawable 키워드를 이용하는 걸 보면 객체화된 이미지도 결국 하나의 리소스로 취급이 되는 것 같다.
드로어블 파일 내의 여러 요소들은 더 알아봐야겠다!
쉐이프 드로어블(ShapeDrawable)
xml로 도형을 그릴 수 있는 드로어블이다.
상태 드로어블에서의 <selector> 태그를 <shape>으로 바꾸면 된다!
태그들이 많아서 가볍게 정리했다!
태그 | 설명 | 속성 |
<shape> | 도형 태그 |
|
<size> | 도형 크기 지정 |
|
<stroke> | 테두리 선 속성 지정 |
|
<solid> | 도형 채우기 |
|
<padding> | 테두리 안쪽 공간 설정 |
|
<gradient> | 그라데이션 | |
<corners> | 테두리 둥글게 |
|
<layer_list> 태그를 사용하면 여러 개의 그래픽을 사용할 수 있어서, 더 다채롭게 만들 수 있다.
이렇게 된다! 실제로 버튼 커스텀도 이런 식으로 하는지는 모르겠다.
메모
쉐이프 드로어블에서 크기를 지정하지 않으면 뷰의 크기에 따라서 유동적으로 조절이 되는 것 같다. 크기를 지정했을 때에는 뷰에 따라 테두리 같은 게 잘리거나 조금 이상하게 나왔기 때문이다.
아까 드로어블도 결국 리소스로 취급이 된다고 했었는데, 그러면 상태 드로어블 파일에서 쉐이프 드로어블을 가져다 쓸 수 있지 않을까? 하는 생각으로 해봤는데 된다!
저 그라데이션 버튼은 밑의 상태 드로어블을 이용해 누르면 색이 나타나는 형태로 구현했다(사진은 누른 상태이다).
<?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/gradient_button"/>
</selector>
https://developer.android.com/reference/android/graphics/drawable/Drawable
Drawable | Android Developers
developer.android.com
'안드로이드 > 안드로이드 앱 프로그래밍' 카테고리의 다른 글
10. 테이블 레이아웃(TableLayout) (0) | 2023.04.13 |
---|---|
프로젝트: 영화 상세화면 만들기 (0) | 2023.04.13 |
8. 프레임 레이아웃(FrameLayout) (0) | 2023.04.13 |
7. 상대 레이아웃(RelativeLayout) (0) | 2023.04.13 |
6. 위젯 (0) | 2023.04.13 |