ListView는 App 에서 목록을 구현하는데 사용된다.
ListView는 getView() 메소드를 사용해서 동작하게 되는데,
만약 ListView에 20개의 아이템을 출력해야 한다면, getView() 에서 화면에 출력할 View를 inflate 를 20번 준비하여 해당 View에 필요한 데이터를 담아서 출력하게 된다.
즉, 똑같이 생긴 View를 20번 inflate하게 되는 것이다.
똑같이 생긴 View를 재사용할 수 없다.
아이템 개수가 20개를 넘어서 1억개가 된다면,
1억번의 같은 view를 inflate 하게 된다면 메모리와 성능에 악영향을 미칠 수 있다.
그래서 나온 것이 ViewHolder 라는 개념이다.
ListView에 ViewHolder 패턴을 적용하게되면,
생김새가 다른 View를 사용할 때에만 inflate 를 할 수 있다.
즉 같은 View의 아이템이라면, 최초 1회만 View를 inflate하여 ViewHolder에 임시 저장하고 재사용할 수 있는 것이다.
getView(final int position, View convertView, ViewGroup parent) {
// 최초에 convertView가 null이므로, inflate를 처리한다
if (convertView == null) {
// 전역으로 생성한 rootView에 inflate
rootView = inflater.inflate(R.layout.item_list, null);
// ViewHolder을 생성
Holder holder = new Holder();
holder.tv = (TextView) rowView.findViewById(R.id.text);
holder.img = (ImageView) rowView.findViewById(R.id.image);
// setTag : holder 임시 저장
rootView.setTag(holder);
} else {
// rootView에 convertView를 셋팅
rootView = convertView;
// rootView에서 holder을 꺼내온다
holder = (Holder) rootView.getTag();
}
holder.tv.setText(result[position]);
holder.img.setImageResource(imageId[position]);
rowView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "You Clicked " + result[position], Toast.LENGTH_LONG).show();
}
});
return rootView;
}
convertView == null 일 경우에만 inflate 와 findViewById 가 호출되어 view가 생성된다.
장점
단점
RecyclerView는 기존의 ListView에서 한개 이상의 View를 적용하기 힘든 단점을 보완할 수 있다.
RecyclerView 를 사용해서 아이템을 더 다양한 형태로 커스터마이징 할 수 있다. 개발자는 LayoutManager 와 ViewHolder 패턴을 의무적으로 사용해야하고. Item 에 대한 View의 변형이나 애니매이션을 넣을 수 있는 개념이 추가된 것이다.
LayoutManager 를 사용해서 가로, 세로 형태로 아이템을 배치할 수 있다.
리사이클러뷰는 다음의 3가지 인터페이스를 의무적으로 구현해야한다.
// 뷰 홀더를 생성하고 뷰를 붙여주는 부분
onCreateViewHolder(ViewGroup parent, int viewType)
// 재활용되는 뷰가 호출하여 실행되는 메소드,
// 뷰 홀더를 전달하고 어댑터는 position의 데이터를 결합시킨다.
onBindViewHolder(CustomViewHolder holder, int position)
// 데이터의 개수 반환
getItemCount()