MyCloud

[안드로이드] ViewHolder 패턴에 대한 이해 본문

Programming/Android

[안드로이드] ViewHolder 패턴에 대한 이해

Swalloow 2016. 5. 27. 02:47



ViewHolder 패턴의 등장



 뷰 홀더(ViewHolder) 패턴은 리스트 뷰의 유연한 동작을 위해 나타나게 되었습니다.

 예를 들어, 리스트가 1000개 있다고 생각해보겠습니다.

 왼쪽과 같은 리스트 뷰는 TextView 3개로 구성되어 있습니다.

 TextView를 생성하기 위해 매번 findViewById()를 호출해야 할 것이고,

 3000번 호출된다면, 이는 엄청난 성능 오버헤드를 불러오게 됩니다.

 아마 스크롤 내릴 때마다 매우 느린 반응속도를 보일 것입니다.

 이를 해결하기 위해 ViewHolder 패턴이 나타났습니다.

 ViewHolder 패턴의 원리는 각 View 객체를 ViewHolder 에 홀드 시키는 것입니다.

 이러한 방법으로 리스트 뷰에서의 성능을 개선할 수 있습니다.








ViewHolder 패턴 사용방법


ViewHolder 패턴을 사용하기 위해서는 먼저 다음과 같이 ViewHolder 클래스를 정의해야 합니다.

ViewHolder 클래스 안에는 각 컴포넌트 View를 넣어주시면 됩니다.

static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}


사용할 때는 ViewHolder 클래스를 생성하고 각 Attribute에 findViewById() 메서드를 통해 채워주어야 합니다.

마지막으로 setTag() 메서드를 통해 레이아웃 내부에 저장합니다.

ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);


하지만 위와 같은 방식을 사용한다면, 서로 다른 리스트 뷰가 생길 때마다

매번 ViewHolder 객체를 정의해주어야 하는 번거로움이 있습니다.

이를 해결하기 위해 동적으로 생성하는 코드를 찾아보았습니다.


참조 : http://www.kmshack.kr/2013/09/android-%EC%9C%A0%EC%97%B0%EC%84%B1-%EC%9E%88%EB%8A%94-viewholder-pattern/

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;
}
}

ViewHolder가 없으면 SparseArray를 통해 생성하고, 자식 뷰에 findViewById() 를 실행하는 것입니다.


구글 공식문서 : https://developer.android.com/training/improving-layouts/smooth-scrolling.html#AsyncTask



Comments