올해는 머신러닝이다.
listview 최적화하기 2/2 본문
출처 : http://tigerwoods.tistory.com/17
파트 1에 이어 파트 2에서는
사용자와 interact가 가능한 ListView의 구현과
이를 재사용 가능 하도록 하는 방법에 대해 다룹니다.
재사용 가능한 커스텀 ListView에 관한 부분은
지금까지 다룬 모든 ListView관련 노하우 + @ 가
사용 됨으로 전 포스팅의 내용을 모두 숙지 하고 계셔야 이해가 쉬울 것 같습니다.
4. Interactive ListView 만들기
지금까지는 Static한 ListView만 살펴봤지만, 사용자와 교감(interact)이 가능한 ListView를 만들 수도 있다.
예를 들면, mp3플레이어 플레이 리스트에 별표의 개수를 저장할 수 있도록 하여 특정 곡에 대한 선호도를 지정할 수 있을 것이다. (iPod에서 처럼)
이를 위해서는 ListView의 row에 RatingBar 위젯을 사용해야 하는데, 여기에는 몇 가지 문제가 있다.
우선 RatingBar객체는 사용자로부터 임의의 값을 입력 받지만 ListView의 각 row에 그려질 때 마다 getView() 내부에서 리싸이클 (바로 전에 설명한 holder pattern 때문에)되기 때문에 사용자로부터 입력 받은 값을 어딘가에 저장할 필요가 있다. 그래야 RatingBar가 다시 그려져야 할 때 기존에 입력 받은 값을 그대로 복원 해서 user에게 보여 줄 수 있기 때문이다.
하지만 Rating Bar 객체는 기본적으로 단순한 UI 위젯에 불과하며 사용자가 입력한 값을 저장하는 기능이 없다. 그래서 우리는 사용자가 입력한 값을 ListView의 각 row 별로 rating값을 저장하는 방법을 찾아야 한다.
책에서 설명하는 방법을 간단하게 요약하면 다음과 같다.
- 한 row의 정보(별표 rating 표현을 위한 float 형, text 메시지 표시를 위한 String 형)를 저장 가능한 RowModel이라는 커스텀 클래스를 디자인한다.
- RowModel을 요소로 같는 ArrayList를 구성하여 사용될 아답터에 공급한다.
- ArrayAdapter에서 상속받는 커스텀 아답터를 구현하고 row가 화면에 표시될 때 마다 호출되는 getView() method를 overriding한다. getView내부에서는 rating이 변하면 발생하는 event Listener를 지정하고, row의 상태변화를 해당 RowModel 인스턴스에 저장/로드 한다.
위의 내용을 그림으로 도식화 하면 다음과 같은 구조가 된다.
커스텀 Adapter내부의 오버라이딩된 getView() 는
전 단락에서 사용한 convertView와 holder pattern을 이용한 최적화가 되어있어 처음에는 조금 복잡하게
느껴질 수도 있지만 기본적인 개념은 다음과 같다.
다음 예제는 각 row가 RatingBar + TextView로 이루어진 ListView이며,
RatingBar가 사용자에 의해 최대값으로 설정되면 해당 row의 text가 대문자로 변하게 된다.
layout 파일(main.xml; row.xml)은 전 단락의 예제와 동일 하다.
Interactive한 ListView 예제 (MyFancyListView05.java)
소스 펼치기
5. Custom ListView의 재활용
위에서 사용된 ListView의 구현 방법은 잘 작동하지만 코드의 재사용이 힘들다는 단점이 있다.
이번 단락에서는 재사용이 가능토록 설계된 코드 디자인을 소개한다.
먼저, 소개될 디자인을 간단한 UML class diagram으로 나타내면 다음과 같다.
위에서 main activity인 ReusableListViewDemo 클래스가 하는 일은
단순히 main.xml(RatingBarListView 클래스사용 됨)을 이용해 activity의 화면을 구성하고
ListView의 각row에 표시될 text만 ArrayAdapter<String>을 통해 커스텀 ListView(RatingBarListView)에
공급하는 것이 전부이다.
ArrayAdapter<String> 객체를 전달받은 커스텀 ListView는 오버라이드된 setAdapter() 메소드를
통해 ArrayAdapter<String> 객체를 RatingBarListAdapter에 전달하고 RatingBarListAdapter의 getView()에서
RatingBar와 ArrayAdapter<String>객체의 text를 합쳐 RatingBar+Text 형태의 row layout을 구성하게 된다.
RatingBarListAdapter 클래스에는 두 가지의 중요한 기능이 구현되어 있는데,
첫째로는 ListView내부 각 row의 RatingBar 값(얼마나 많은 별표가 선택되었는지)을 저장하는 저장소의 역할이고,
두 번째로는 바로 전에도 언급한 getView() 메소드를 오버라이딩하여 ListView의 row의 모양/기능을 결정하는 것이다.
그렇기 때문에, RatingBarListAdapter 클래스만 수정하고 이와 연관관계에 있는
클래스: ViewWrapper, RatingBarListView만 RatingBarListAdapter의 변경사항에 대응토록
수정한다면 새로운 형태/기능의 row를 제공하는 ListView를 쉽게 구현 할 수 있다.
앞으로 소개될 예제의 RatingBarListAdapter:getView()에서 row 객체가 조립되는 순서를 시각화 하면 다음과 같다.
(마지막에 첨부된 예제 소스와 같이 분석하면 좋을것 같네요~)
RatingBarListAdapter:getView()에서 view 구성순서 1 (convertView == null인 경우)
이미지 펼치기
RatingBarListAdapter:getView()에서 view 구성순서 2 (convertView != null인 경우)
이미지 펼치기
위의 class diagram과 getView에서의 row 생성 순서 이미지를 참조하여
압축 파일로 첨부한 프로젝트 소스를 분석하면 재사용 가능한 RatingBar를 포함한 ListView가
어떻게 설계 되었는지 좀더 쉽게 분석 할 수 있을 것이다.
재사용 가능한 ListView demo 소스 다운받기
'Android > Tip&Tech' 카테고리의 다른 글
Photoshop like color picker (3) | 2011.05.24 |
---|---|
[펌]android trigger 참고 (0) | 2011.05.24 |
listview 최적화하기 (0) | 2011.05.19 |
출시 준비를 위한 체크 리스트 (0) | 2011.05.18 |
android mapview overlay and draw path (1) | 2011.05.18 |