ViewHolder를이용한 최적화
이 강좌에 이어서 진행하도록하겠습니다.
MyListAdapter에서 다음과 같은 코드를 작성했었습니다.
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.item,null);
nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
content_textView = (TextView)convertView.findViewById(R.id.content_texview);
date_textView = (TextView)convertView.findViewById(R.id.date_textview);
title_textView =(TextView)convertView.findViewById(R.id.title_textview);
profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
}
convertView == null 이라는 부분이 생각보다 많이 호출되어 LayoutInflater를 통한 xml을 불러오는 부분이 많이 실행됩니다.
LayoutInflater를 통해서 xml을 불러오는 부분이 생각보다 무거운작업이라고 전문가들을 말합니다.
따라서 Holder패턴이라는 패턴을 통해서 최적화하는 방법을 설명해드리겠습니다.
MyListAdapter에 다음과같은 inner class(내부 클래스를 만듭니다.)
class ViewHolder{
}
이 inner클래스에 위에서 사용했던 아이템을 구성했던 뷰의 멤버들을 옮겨줍니다.
class MyListAdapter extends BaseAdapter{
Context context;
ArrayList<list_item> list_itemArrayList;
/여기있었던 뷰를구성하는 멤버들을 viewHolder 클래스 안으로 이동
class ViewHolder{
//여기로 이동
TextView nickname_textView;
TextView title_textView;
TextView date_textView;
TextView content_textView;
ImageView profile_imageView;
}
}
이 후 ViewHolder 클래스 멤버를 만들어줍니다.
class MyListAdapter extends BaseAdapter{
Context context;
ArrayList<list_item> list_itemArrayList;
ViewHolder viewholder;//클래스맴버 만듬
class ViewHolder{
//여기로 이동
TextView nickname_textView;
TextView title_textView;
TextView date_textView;
TextView content_textView;
ImageView profile_imageView;
}
}
이제 getView 메소드 부분을 수정해야합니다.
viewHolder객체를 LayoutInflater.from 밑부분에 생성해줍니다
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.item,null);
//객체를 생성
viewholder = new ViewHolder();
.
.
.
.
그 다음 바로 밑의 오류가 나던
nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
content_textView = (TextView)convertView.findViewById(R.id.content_texview);
date_textView = (TextView)convertView.findViewById(R.id.date_textview);
title_textView =(TextView)convertView.findViewById(R.id.title_textview);
profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
viewholder.을 붙여줍니다.(기존에 있던 위젯 멤버들을 viewHolder클래스로 이동했기 때문에 변경해야함)
viewholder.nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
viewholder.content_textView = (TextView)convertView.findViewById(R.id.content_texview);
viewholder.date_textView = (TextView)convertView.findViewById(R.id.date_textview);
viewholder.title_textView =(TextView)convertView.findViewById(R.id.title_textview);
viewholder.profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
그 다음 convertView.setTag(viewholder); 다음과 같은 메소드를 추가하여줍니다.
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.item,null);
viewholder = new ViewHolder();
viewholder.nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
viewholder.content_textView = (TextView)convertView.findViewById(R.id.content_texview);
viewholder.date_textView = (TextView)convertView.findViewById(R.id.date_textview);
viewholder.title_textView =(TextView)convertView.findViewById(R.id.title_textview);
viewholder.profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
convertView.setTag(viewholder);
}
if(convertView==null){
} 에
else문을 추가하고 다음과 같은 코드를 추가하여줍니다.
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.item,null);
viewholder = new ViewHolder();
viewholder.nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
viewholder.content_textView = (TextView)convertView.findViewById(R.id.content_texview);
viewholder.date_textView = (TextView)convertView.findViewById(R.id.date_textview);
viewholder.title_textView =(TextView)convertView.findViewById(R.id.title_textview);
viewholder.profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
convertView.setTag(viewholder);
}else{
viewholder = (ViewHolder)convertView.getTag();
}
이제 아래에 오류가 나고있는 위젯들도 위에서 한것과같이
viewholder.을 붙여줍니다.(기존에 있던 위젯 멤버들을 viewHolder클래스로 이동했기 때문에 변경해야함)
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.item,null);
viewholder = new ViewHolder();
viewholder.nickname_textView = (TextView)convertView.findViewById(R.id.nickname_textview);
viewholder.content_textView = (TextView)convertView.findViewById(R.id.content_texview);
viewholder.date_textView = (TextView)convertView.findViewById(R.id.date_textview);
viewholder.title_textView =(TextView)convertView.findViewById(R.id.title_textview);
viewholder.profile_imageView = (ImageView)convertView.findViewById(R.id.profile_imageView);
convertView.setTag(viewholder);
}else{
viewholder = (ViewHolder)convertView.getTag();
}
viewholder.nickname_textView.setText(list_itemArrayList.get(position).getNickname());
viewholder.title_textView.setText(list_itemArrayList.get(position).getTitle());
viewholder.content_textView.setText(list_itemArrayList.get(position).getContent());
viewholder.date_textView.setText(list_itemArrayList.get(position).getWrite_date().toString());
viewholder.profile_imageView.setImageResource(list_itemArrayList.get(position).getProfile_image());
return convertView;
}
최적화가 완료되었습니다. 이제 실행을하여 결과를확인해봅니다.
별 차이를 느낄수 없으실수도있지만 리스트의 사이즈를 늘려서 비교해보면 차이를 느끼실수 있습니다.
이제 다음 강좌에서는 Glide라는 라이브러리를 사용하여 외부에있는 이미지를 우리의 리스트의 프로필이미지로 연결하는 법을 실습하겠습니다.