일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- game
- 안드로이드
- tcp네트워크
- 어플
- 기업의 행포
- 아이폰
- 에셋
- unity
- 리눅스
- 스랄 특성
- php 홈디렉토리 변경방법
- 명령어
- 비행기 모드
- 포트(Port)
- 집 정리
- 벨팡
- Collection Framework
- TCP 네트워크 방식의 연결
- tcp
- End of Darkness
- 소캣(Socket)
- 게임
- 나지보
- 자바
- 안드로이드 Application Lifecycle
- 아이패드
- 나지보 특성
- 변경된 정보
- 히오스
- 컬렉션 프레임
- Today
- Total
Do Something IT
[번역] 안드로이드 Drawable Mutations 본문
Drawable Mutations
이번엔 구글 개발자 사이트의 기술 문서 중, 짤막한 내용을 번역해 보았습니다. 어플리케이션 개발(특히 GUI) 에 엄청나게 많이 활용되는 Drawable, 그 중에서도 상당히 유용해 보이는(적어도 문서상으로는...) muate 함수 관련된 내용입니다. Drawable 이 실제 Bitmap Data 등과는 어떤 관계를 갖고 있는지 대략적으로 감을 잡을 수 있겠네요.
안드로이드 Drawable 은 어플리케이션을 작성하는데 굉장히 큰 도움을 준다. Drawable 은 일반적으로 View 와 연관되어 사용되며, 쉽게 교체할 수 있는 그림을 담는 상자(Drawing Container) 이다. 예를 들어 BitmapDrawable 은 이미지를 표시하는데 사용되며, ShapeDrawable 은 도형이나 그라데이션등을 그리는데 사용된다. 또한, 개발자는 좀 더 복잡한 랜더링을 위해, Drawable 들을 결합할 수도 있다.
Drawable 은 개발자들이 안드로이드에서 제공하는 위젯들을 상속받아 새로운 클래스를 만들지 않고도, 화면상에 그려지는 위젯의 모습을 변경할 수 있게 해준다. 사실 Drawable 은 너무나 편리해서, 대부분의 안드로이드 기본 어플리케이션과 위젯들은 Drawable 을 이용해서 만들어 졌다. 실재로 안드로이드 프레임워크 코어 단에는 약 700 개의 Drawable 이 사용된다. Drawable 들은 매우 광범위하고 빈번하게 사용되고 있음으로, 안드로이드는 효율적인 방식으로 리소스로부터 Drawable 을 로드한다.
예를 들어 개발자가 매번 새로운 버튼을 생성할때 마다, 새로운 Drawable 인스턴스(android.R.drawable.btn_default
)가 안드로이드 프레임워크의 리소스에서 로드된다. 즉, 어플리케이션에서 사용되는 버튼들은 모두 서로 다른 Drawable 인스턴스를 갖고 있다는 뜻이다. 그러나 버튼에 대한 모든 Drawable 들은 하나의 'Constant State' 를 공유한다. Constant State 에 포함되는 값은 Drawable 의 종류에 따라 다르지만, 일반적으로 리소스 파일내에서 정의할 수 있는 모든 속성값을 포함한다. 버튼의 Constant State 는 Bitmap 이미지를 포함한다. 따라서, 어플리케이션에서 사용되는 모든 버튼은 동일한 Bitmap 이미지를 공유해서 사용하고, 해당 이미지는 메모리 상에 한번만 로드되면 됨으로 메모리를 크게 절약할 수 있다.
다음의 다이어그램은 두 개의 서로 다른 View 에서, 서로 동일한 이미지 리소스를 배경으로 설정 할 때, 어떤 구성요소들이 생성되는지 보여 준다. 아래 그림에서와 같이 두 개의 Drawable 인스턴스가 생성되지만, 두 개의 인스턴스는 서로 동일한 Constant State - Bitmap 이미지 를 공유한다.
이렇게 서로 다른 Drawable 이 동일한 Constant State 를 공유하는 것은 메모리 낭비를 크게 줄여주지만, 개발자가 Drawable 의 속성값을 변경하고자 한다면 문제를 야기할 수도 있다. 예를 들어 책 목록 (혹은 음악 목록)을 보여주는 어플리케이션을 상상해 보자. 각 책이름 옆에서 반투명한 별 표시가 있고, 사용자는 자신이 좋아하는 책에 대하여, 별을 클릭해 표시할 수 있다. 이런 기능을 구현하기 위해 개발자는 아마도 ListAdapter 의 getView() 메서드에 아래와 같은 코드를 작성할 것이다.
Book book = ...;
TextView listItem = ...;
listItem.setText(book.getTitle());
Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
star.setAlpha(255); // opaque
} else {
star.setAlpha(70); // translucent
}
그러나 불행히도, 이 코드는 잘 작동하지 않는다. 사용자의 선택과는 관계없이 모든 별은 똑같이 반투명하거나, 똑같이 불투명하게 표시된다.
하지만, 다행이도 안드로이드 1.5 이 후 버전 에서는 Constant State 가 모든 인스턴스간에 공유되기 때문에 발생하는 문제를 해결하기 위한 간편한 방법을 제공한다. 개발자가 Drawable 의 mutate() 메서드를 호출 하면, 해당 Drawable 의 Constant State 가 복제되고, 개발자는 다른 인스턴스들에게 영향을 주지 않고 마음대로 원하는 속성 값을 변경할 수 있다. 또한가지 중요한 사실은 Constant State 는 복제되더라도, Bitmap 리소스는 여전히 공유된다는 점이다. 아래의 다이어그램은 개발자가 mutate() 메서드를 호출 한 후 어떤 일이 일어나는지 보여준다.
이제, 이전 코드를 mutate 메서드를 이용해서 수정해 보자.
Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
star.mutate().setAlpha(255); // opaque
} else {
star. mutate().setAlpha(70); // translucent
}
mutate() 메서드는 Drawable 자체를 반환한다. 이때, 반환된 Drawable 은 자기 자신이며, 새롭게 생성된 것은 아니다. 이는, 개발자가 추가적인 메서드를 바로 뒤 이어서 호출(Chain method call) 할 수 있도록 해주기 위해서 이다. 새롭게 수정한 코드는 아래와 같이 정상적으로 동작한다.
'Android' 카테고리의 다른 글
안드로이드 Application Lifecycle (0) | 2010.07.08 |
---|---|
[Android] Adapter (0) | 2010.06.25 |
움직이는 네모 (0) | 2010.06.21 |
기념일자 찾기 (0) | 2010.06.17 |
안드로이드 애플리케이션 구성요소 (0) | 2010.06.08 |