Notice
Recent Posts
Recent Comments
올해는 머신러닝이다.
[펌]서로다른 뷰 viewHolder 구현하기 본문
출처 : http://www.kmshack.kr/346
얼마전 ListView 포퍼먼스 팁에 관한 블로그 포스팅을 한적이 있다. Adapter에서 View의 재활용과 함께 ViewHolder Pattern으로 findViewById를 View생성 시점에 setTag()
를 하여 재활용에 대해 언급 했다.
이 방법은 각 ListView의 ViewItem별로 각각의 ViewHolder를 가지고 있어야 한다.
ListView의 아이템별로 서로 다른 디자인이 필요하기에 View의 종류가 달라 질 수 밖에 없기때문에 ViewHolder도 각각 존재 할 수 밖에 없다. 이렇게 static하게 ViewHolder을 가지고 있는것 보다 유연하게 ViewHolder를 생성 할 수 있는 코드를 생성하는 방법에 대해서 알아보자.
아래처럼 Adapter에 static class로 만들어 ViewHolder를 사용하는것이 일반적이다. ViewHolder는 같은 기능을 하는데 단순히 View의 종류가 달라져 각각 생성 할수 밖에 없는 상황이다.
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
32
33
34 |
private static class ViewHolder { public final ImageView bananaView; public final TextView phoneView; public ViewHolder(ImageView bananaView, TextView phoneView) { this .bananaView = bananaView; this .phoneView = phoneView; } } @Override public View getView( int position, View convertView, ViewGroup parent) { ImageView bananaView; TextView phoneView; if (convertView == null ) { convertView = LayoutInflater.from(context).inflate(R.layout.banana_phone, parent, false ); bananaView = (ImageView) convertView.findViewById(R.id.banana); phoneView = (TextView) convertView.findViewById(R.id.phone); convertView.setTag( new ViewHolder(bananaView, phoneView)); } else { ViewHolder viewHolder = (ViewHolder) convertView.getTag(); bananaView = viewHolder.bananaView; phoneView = viewHolder.phoneView; } BananaPhone bananaPhone = getItem(position); phoneView.setText(bananaPhone.getPhone()); bananaView.setImageResource(bananaPhone.getBanana()); return convertView; } |
해결책으로 아래와 같이 ViewGroup의 View들에 대해 동적으로 생성하는 코드를 만들 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
public class ViewHolder { @SuppressWarnings ( "unchecked" ) public static <T extends View> T get(View view, int id) { SparseArray<View> viewHolder = (SparseArray<View>) view.getTag(); if (viewHolder == null ) { viewHolder = new SparseArray<View>(); view.setTag(viewHolder); } View childView = viewHolder.get(id); if (childView == null ) { childView = view.findViewById(id); viewHolder.put(id, childView); } return (T) childView; } } |
모든 View들은 View를 상속 받고 있기 때문에 SparseArray를 통해서 ChildView의 Id가 없으면 findViewById()
를 통해 put해주고 있으면 get으로 가져오는 방식이다.
사용하는 간단한 예를 알아보면:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
@Override public View getView( int position, View convertView, ViewGroup parent) { if (convertView == null ) { convertView = LayoutInflater.from(context).inflate(R.layout.banana_phone, parent, false ); } ImageView bananaView = ViewHolder.get(convertView, R.id.banana); TextView phoneView = ViewHolder.get(convertView, R.id.phone); BananaPhone bananaPhone = getItem(position); phoneView.setText(bananaPhone.getPhone()); bananaView.setImageResource(bananaPhone.getBanana()); return convertView; } |
기존의 방법보다 더 간결화되고 심플해진 것을 볼 수 있다.
'Android > Tip&Tech' 카테고리의 다른 글
절대로 죽지않는 좀비 서비스 만들기 (0) | 2013.11.27 |
---|---|
[펌]Pull To Refresh for Android (0) | 2013.11.25 |
[펌]Create a transparent progress dialog on Android (0) | 2013.10.31 |
[펌][안드로이드] Event 처리 메커니즘 (0) | 2013.09.16 |
[펌]Android App Widget 관련 상세한 설명 (0) | 2013.09.06 |