출처 : http://iam1492.tistory.com/33
조금 수정..
@Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(v == null) { LayoutInflater inflater = LayoutInflater.from(mContext); v = inflater.inflate(R.layout.layout_list_item, null); } TextView txtName = (TextView)v.findViewById(R.id.txtName); TextView txtMail = (TextView)v.findViewById(R.id.txtMail); Contact entry = mList.get(position); txtName.setText(entry.getName()); txtMail.setText(entry.getMail()); return v; }
ViewHolder 를 적용하기 전에는 항상 xml 리소스에 접근하게 되며 성능 저하의 원인이 된다.
[View Holder 적용 후]
@Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView;
ViewHolder holder;if(v == null) { LayoutInflater inflater = LayoutInflater.from(mContext); v = inflater.inflate(R.layout.layout_list_item, null); holder = new ViewHolder(); holder.txtName = (TextView)v.findViewById(R.id.txtName); holder.txtMail = (TextView)v.findViewById(R.id.txtMail); v.setTag(holder); }else{
holder = (ViewHolder)v.getTag();
}
Contact entry = mList.get(position);
if(entry != null) {
holder.txtName.setText(entry.getName());
holder.txtMail.setText(entry.getMail());
}
return v;
}
static class ViewHolder {
TextView txtName;
TextView txtMail;
}
이런식으로 ViewHolder 클래스를 만들고 처음 한번만 xml 리소스의 접근할 경우 getView 가 불릴때 마다 findViewByID 를 할 필요가 없어져 성능이 좋아진다.
(위 예제의 경우 성능 차이를 느낄 수 없겠지만 실제로 복잡한 레이아웃의 경우 체감 성능에 많은 개선이 있다.)
그런데 얼마전 회사 동기가 View Holer 는 죽었다며 한 블로그 포스팅을 공유해줬다. 포스팅 제목은: View Holder is dead. Long live setTag 였다.
무슨 내용인가 유심히 읽어 보니 안드로이드에서 1.6이후에 setTag(int key, Object tag) 라는 메소드를 지원해준다는 것이다.즉, 따로 ViewHolder 클래스를 만들 필요가 없다는 것이다. 바로 적용해 보았다.
[ setTag(int key, Object tag) 메소드 적용 후]
@Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView;
TextView txtName;
TextView txtMail; if(v == null) { LayoutInflater inflater = LayoutInflater.from(mContext); v = inflater.inflate(R.layout.layout_list_item, null); //View Holder 에 넣었던 부분을 setTag(key,tag) 메소드로 대체한다. v.setTag(R.id.txtName, v.findViewById(R.id.txtName)); v.setTag(R.id.txtMail, v.findViewById(R.id.txtMail)); }else{
txtName= (TextView)v.getTag(R.id.txtNam); txtMail= (TextView)v.getTag(R.id.txtMail);
} Contact entry = mList.get(position); if(entry != null) { txtName.setText(entry.getName()); txtMail.setText(entry.getMail()); } return v; }
성능 차이는 크게 나지 않는다~
결과적으로 View Holder is dead란 제목은 좀 적절해 보이지는 않으나, 이런것도 있구나 하는 걸 새로 알게됐다.(왜 그동안 이 메소드가 안보였는지...)
혹시 아직도 getView 혹은 bindView시에 항상 xml 리소스에 접근해 리소스 객체를 가져오고 있다면, ViewHolder 나 setTag(int key, Object tag) 둘중 하나의 방법으로 소스를 고쳐보자. 훨씬 부드럽게 스크롤되는 알흠다운 모습을 볼 수 있을 것이다.
'안드로이드 개발 팁' 카테고리의 다른 글
안드로이드 ExpandableListView 구현 관련 (0) | 2014.07.15 |
---|---|
안드로이드 레디오 버튼 버튼배경 바꾸기 (0) | 2014.07.15 |
android 유투브 강의 (0) | 2014.06.12 |
android 페이지 목록 동적으로 처리하기 (0) | 2014.05.29 |
android textview setlayoutparams programmatically (0) | 2014.05.29 |