Android/App개발2011. 6. 3. 16:42
http://sites.google.com/site/endihom/home/programming-language/android/article/listview-backgrounds

ListView 는 안드로이드에서 가장 널리 사용되는 위젯이다. 사용하기 쉽고, 매우 유연하며 강력하다. ListView는 가끔 이해하기 어려울수 있다.

ListView에서 나타나는 가장 공통된 이슈중에 하나는 커스텀 백그라운드를 사용하고자 할때이다. 다른 안드로이드 위젯처럼 디플트로 ListView는 반투명 배경을 가질수 있는데 이는 개발자가 매우 어두운 회색(현재 다크 테마에서는 #FF191919)디폴트 윈도우 배경을 통해 볼수 있다는 것을 뜻한다. 게다가 ListView는 fading edges를 기본적으로 제공한다. 아래의 스크린샷의 윗 부분을 보면 첫번째 아이템이 점차 검은색으로 페이드 되는것을 알수 있다. 이 기술은 스크롤되는 컨테이너를 가지는 시스템에서 전반적으로 사용된다.

Android's default ListView

패이드 효과는 Canvas.saveLayerAlpha() 와 Porter-Duff Destination Out blending 모드의 조합으로 구현되어 진다.

불행하게도, ListView에서 커스텀 배경을 사용하거나 윈도우의 배경을 변경할때 화면이 이상하게 보일 것이다. 아래 두개의 스크린샷은 윈도우 배경을 변경했을때 어플리케이션에서 어떤일이 일어나는지를 보여준다. 첫번째 화면은 디폴트로 리스트가 어떡해 보여지는지를 볼수 있고 두번째 화면은 터치 제스쳐를 통해 초기화되어 스크롤되는 동안의 모습이다.

Dark fade Dark list

이 랜더링 이슈는 안드로이드 프레임워크가 ListView의 모든 인스턴스에 기본적으로 적용된 최적화 기법에 의한 것이다. 앞서 언급한데로 페이드 효과는 Porter-Duff blending mode를 사용해 구현되었다. 이 구현방법은 정말 잘 동작하지만 화면에 보이지 않는 비트맵에서 렌더링의 일부분을 캡쳐해야 함으로서 매우 고비용이며 드로잉 성능을 저하시킬수 있다. 그래서 추가적인 blending(메모리로부터 다시 읽어 들이는 것을 의미)이 필요하다 

ListView는 거의 대부분 고정 배경화면에서 디스플레이되기 때문에 고비용이 드는 작업으로 내려갈 이유가 없다. 이것이"cache color hit"라 불리는 최적화를 소개하는 이유다. 캐쉬 컬러 힌트는 윈도우의 배경색에 기본적으로 설정되어 있는 RGB색으로 안드로이드 dark테마에서 #191919이다. 이 힌트가 설정되면 ListView(사실 이 클래스의 부모 클래스)는 단일 배경화면으로 그릴 것이므로 고비용의 saveLayerAlpha()와 Porter-Duff 렌더링을 단순한 그레디언트로 대체할수있다는 것을 알게 된다. 이 그레디언트는 완전히 투명한 컬러에서 캐시 컬러 힌트 값까지 그레디언트 되고 이미지 위에서 리스트 바닥에 dark 그레디언트된 보고자 하는 바로 그것이다.

앞서 언급한데로 Listview와 안드로이드 UI 툴킷의 모든 기본 위젯들은 기본적으로 투명/반투명 배경을 가지진다. 이것은 ListView가 child를 다시 그릴때 윈도우 배경과 child를 반드시 혼합(blend)해야한다는 것을 뜻한다. 다시 한번 말하지만, 이것은 고비용의 메모리 다시 읽기를 초래하며 이 메모리 다시 읽기는 초당 수십번의 다시 그리기가 발생하므로 스크롤이나 플리핑하는동안 성능이 매우 떨어지게된다.

스크롤하는 동안 그리기 성능을 향상 시키기 위해 안드로이드 프레임워크는 cache color hint를 재사용한다. 이 힌트가 설정되면 프레임워크는 힌트값(scrolling cache라는 또다른 최적화 기법이 적용되지 않은 상태라고 가정하자)으로 채워진 비트맵안 리스트의 child를 복사한다. 그럼 다음 ListView는 화면에 비트맵을 직접 그린다. 비트맵은 불투명하므로 혼합(blending)이 필요하지 않다. 기본 cache color hint는 #191919이므로 스크롤 되는 동안 각 아이템의 뒤에서 dark 배경색을 볼수 있다.

만약 단일 배경색을 가지지 않거나 hint를 적절한 단일 컬러 값으로 설정한다면 이 이슈를 해결하기 위해 cache color hint 최적화 방법을 꺼 두어야 한다. 코드(setCacheColorHint(int) 참고)나 XML을 적절히 사용(android:cacheColorHint 속성)하여 이 작업을 수행할 수 있다. 최적화를 꺼두기 위해 단순히 투명색 #00000000을 사용하라. 아래의 화면은 XML 레이아웃 파일에 android:cacheColorHint="#00000000"으로 설정한 리스트를 보여준다.

Fade on a custom background

보는것 처럼 나무느낌의 배경화면에서 페이드 효과는 완벽하게 동작한다. cache color hint 기능은 최적화가 어떤 상황에서 개발자를 매우 힘들게 할수도 있으므로 흥미롭다. 하지만 이 특별한 상황에서 기본 동작의 이점은 증가된 복잡도 보다 더 크다.


Posted by 삼스