반응형

 

ViewHolder이란?

 

ViewHolder란 각 뷰들을 보관하는 Holder 객체를 의미하며 이는 RecyclerView 그리고 ListView에서 사용된다.

 

즉, ViewHolder 객체는 레이아웃의 태그 필드 안에 각 구성 요소 뷰를 저장하므로 

반복적으로 조회하지 않고도 즉시 액세스 할 수 있다.

 

하나의 예시를 들어보자.

10개의 데이터를 가진 리스트가 있을 때 이는 리스트 뷰로 표현할 때 어떻게 나타내도 빠른 속도로 나타나게 된다.

하지만 이번에는 100000개의 데이터를 가진 리스트를 생각해보자.

이를 리스트 뷰로 표현하고자 한다면 findViewById()를 호출 할 때 매우 큰 비용이 들기 시작 할 것이다.

직접 해보면 더 도움이 되겠지만, 스크롤을 내릴때 많은 cost를 요구하게 되고 결국 속도 저하를 초래하게 된다.

 

이러한 문제를 해결하기 위해 ViewHolder Pattern이 나타나게 되었다.

이 패턴의 원리는 각 뷰 객체를 뷰 홀더에 보관함으로써 findViewById 같은 반복적으로 호출되는 메서드를 효과적으로 줄여 속도 향상에 많은 기여를 할 수 있는 패턴이다.

 

 

Android의 RecyclerView에서 뷰 홀더를 자주 사용하는 것을 볼 수 있는데,

 

리사이클러 뷰에서 아래 세가지 메서드는 필수로 오버라이딩 해야 한다.

 

onCreateViewHolder = ViewHolder 객체를 생성
onBindViewHolder = ViewHolder 에 data 를 넣는 작업 수행
getItemCount = data의 갯수를 반환 해준다

 

ViewHolder 구현 방법

 

아래는 뷰 홀더를 구현하는 myAdapter 클래스이다.

 

public class myAdapter extends RecyclerView.Adapter<myAdapter.ViewHolder> {
    Context context;

    ArrayList<myItem> items = new ArrayList<myItem>();
    
    public myAdapter(Context context) {
        this.context = context;
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View itemView = inflater.inflate(R.layout.my_item, parent, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        myItem item = items.get(position);
        holder.setItem(item);
    }

    public void addItem(myItem item) {
        items.add(item);
    }

    public myItem getItem(int position) {
        return items.get(position);
    }
}

myAdapter은 RecyclerView.Adapter 클래스를 상속하여 만들어 낸다.

이때 어댑터 안에는 ArrayList 변수를 선언하고 그 안에 여러 개의 myItem 객체가 들어갈 수 있도록 한다.

 

이때 어댑터에는 3개의 메서드를 오버라이딩 해야한다.

 

- onCreateViewHolder 안에서는 각 아이템을 위한 XML 레이아웃을 이용해 뷰 객체를 만든 후 뷰홀더에 담아 리턴한다.

이때 XML 레이아웃을 인플레이션하여 설정할 ViewGroup 객체는 onCreateViewHolder 메소드의 파라미터로 전달된다.

 

- onBindViewHolder 메서드는 뷰 홀더에 각 아이템의 데이터를 설정하게 된다.

즉, setItem 메서드는 myItem 객체를 전달받아 뷰홀더 안에 있는 뷰에 데이터를 설정하는 역할을 한다.

https://www.edwith.org/boostcourse-android/lecture/20492/

 

(참고)inflate란?

 

xml에 쓰여있는 view의 정의를 실제 view객체로 만드는 역할을 수행한다.

(성능상의 문제로 컴파일 타임에 존재하는 xml에 대해서만 적용 가능하다)

 

 

반응형