각 뷰를 보관하는 Holder 객체 = 그릇
ListView / RecyclerView 는 inflate를 최소화 하기 위해서 뷰를 재활용 하는데, 이 때 각 뷰의 내용을 업데이트 하기 위해 findViewById 를 매번 호출 해야합니다. 이로 인해 성능저하가 일어남에 따라 ItemView의 각 요소를 바로 엑세스 할 수 있도록 저장해두고 사용하기 위한 객체
※ inflate? : xml 로 쓰여있는 View의 정의를 실제 VIew 객체로 만드는 것
ListView는 내부에서 화면에 보여질 뷰 배열을 몇개만 생성하고 스크롤 되었을때 이것을 재활용
(Grid View도 마찬가지)
Adapter Class의 getView의 2번째 인자인 convertView로 넘어오게 된다.
이 convertView는 최초 한번만 생성되므로 최초로 호출되는 getView의 convertView는 null값으로 넘어오게 되어 이 특성을 이용해서 convertView == null일때만 Layout을 inflate하고 findViewById()로 view를 ViewHolder에 저장해주고 이것을 다시 converView의 Tag에 저장해주고 다음 호출시에 converView != null이기 때문에 이 처리 부분에서 convertView의 저장된 Tag를 ViewHolder로 캐스팅하여 가져와 view를 바로 꺼내 사용하면된다.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v== null) {
LayoutInflater inflater = LayoutInflater.from(mContext)
v = inflater.inflater(R.layout.layout)list_item, null)
}
TextView txtName = convertView.findViewById(R.id.txt_value_name);
TextView txtMail = convertView.findViewById(R.id.txt_value_mail);
Contact entry = mList.get(position)
txtName.setText(entry.getName());
txtMail.setText(entry.getEmail());
return v;
}
//ViewHolder를 적용하기 전에는 항상 xml리소스에 접근하게 되며 성능 저하의 원인!
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v== null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
v = inflater.inflater(R.layout.layout)list_item, null);
ViewHolder holder = new ViewHolder();
holder.txtName = (TextView)v.findViewById(R.id.txtName);
holder.txtMail= (TextView)v.findViewById(R.id.txtMail);
v.setTag(holder);
}
Contact entry = mList.get(position);
if(entry != null){
ViewHolder holder = (ViewHolder)v.getTag();
holder.txtName.setText(entry.getName());
holder.txtMail.setText(entry.txtMail());
}
return v;
}
static class ViewHolder{
Textview txtName;
Textview txtMail;
}
// ViewHolder 클래스를 만들고 처음 한번만 xml리소스의 접근할 경우,
// getView가 불릴때 마다 findViewById를 할 필요가 없어져 성능이 좋아진다.