본문 바로가기
Android Studio

뷰와 데이터 사이의 중개자 Android 어댑터(Adapter)

by ssury94 2025. 3. 5.

어댑터(Adapter)는 Android에서 UI 요소와 데이터를 연결하는 역할을 하는 중요한 컴포넌트입니다.

일반적으로 RecyclerView, ListView, GridView 등의 뷰에서 사용되며, 뷰와 데이터 사이의 중개자 역할을 합니다.

어댑터의 주요 역할:

  1. 데이터와 뷰 연결:
    • 어댑터는 데이터를 UI 요소와 연결합니다. 예를 들어, 리스트 항목에 표시할 데이터를 준비하고, 이를 각 항목에 대한 에 바인딩합니다.
  2. 데이터의 구조적 표현:
    • 어댑터는 주어진 데이터 집합(배열, 리스트 등)을 UI에서 사용할 수 있는 형식으로 변환합니다. 예를 들어, 배열의 각 항목을 RecyclerView의 항목으로 변환하고 표시합니다.
  3. 아이템 뷰 관리:
    • 어댑터는 각 항목을 ViewHolder를 사용하여 관리하고, 뷰의 재사용을 최적화합니다. RecyclerView에서 onCreateViewHolder()와 onBindViewHolder() 메서드를 사용하여 새로운 뷰를 생성하거나 기존 뷰를 재사용합니다.
  4. UI와 데이터 동기화:
    • 어댑터는 UI에서 데이터 변경을 반영하고, 데이터가 바뀌면 UI를 자동으로 업데이트합니다. 예를 들어, notifyDataSetChanged()를 호출하여 데이터 변경 시 UI를 새로고침합니다.

 

 

1. 어뎁터 상속

package com.marurun66.simplememo.adapter;

import androidx.recyclerview.widget.RecyclerView;

public class MemoAdapter extends RecyclerView.Adapter {
    //1.어뎁터를 상속 받는다.
}

 

 

2. 뷰 홀더 클래스 만들기

public class MemoAdapter extends RecyclerView.Adapter {
    //1.어뎁터를 상속 받는다.

    //2.뷰 홀더 클래스를 만든다.
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        TextView txtBody;
        ImageView imageDelete;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtTitle=itemView.findViewById(R.id.txtTitle);
            txtBody=itemView.findViewById(R.id.txtBody);
            imageDelete=itemView.findViewById(R.id.imageDelete);
        }
    }
}

 

RecyclerView와 ViewHolder

RecyclerView는 많은 데이터를 효율적으로 표시할 수 있는 뷰입니다. 하지만 많은 아이템을 리스트로 표시할 때, 각각의 아이템을 findViewById로 매번 찾는 방식은 성능상 문제가 될 수 있습니다. 이를 해결하기 위해 뷰 홀더 패턴을 사용합니다.

역할

  • 뷰 홀더각각의 아이템을 나타내는 뷰를 저장하는 객체입니다.
  • 각 아이템의 뷰를 한 번만 찾고 이후에는 그 뷰를 재사용할 수 있도록 합니다. 즉, 뷰 홀더가 뷰 객체를 캐시하여 효율적으로 작업할 수 있습니다.

작동 원리

  1. 뷰 홀더 생성: onCreateViewHolder() 메서드에서 뷰를 생성하고, 이 뷰를 뷰 홀더에 저장합니다.
  2. 데이터 바인딩: onBindViewHolder() 메서드에서 데이터를 뷰 홀더에 바인딩합니다. 각 아이템에 대한 뷰를 재사용하기 때문에 성능이 개선됩니다.

 

3. RecyclerView.Adapter에 뷰 홀더 전달

public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {
    //1.어뎁터를 상속 받는다.  //3.만든 뷰 홀더를 적어준다.

    //2.뷰 홀더 클래스를 만든다.
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        TextView txtBody;
        ImageView imageDelete;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtTitle=itemView.findViewById(R.id.txtTitle);
            txtBody=itemView.findViewById(R.id.txtBody);
            imageDelete=itemView.findViewById(R.id.imageDelete);
        }
    }
}

MemoAdapter.ViewHolder는 MemoAdapter 클래스 내에 정의된 ViewHolder 클래스를 의미합니다.

이 ViewHolder 클래스는 각 항목의 UI 요소를 관리하는 역할을 합니다.

MemoAdapter.ViewHolder를 RecyclerView.Adapter에 전달!

 

4. 메서드 오버라이드

public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
    //1.어뎁터를 상속 받는다.  //3.만든 뷰 홀더를 적어준다.

    //2.뷰 홀더 클래스를 만든다.
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        TextView txtBody;
        ImageView imageDelete;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtTitle=itemView.findViewById(R.id.txtTitle);
            txtBody=itemView.findViewById(R.id.txtBody);
            imageDelete=itemView.findViewById(R.id.imageDelete);
        }
    }
}

 

 

 

5. 클래스 멤버 변수와 생성자

public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {
    //5.이 어댑터 클래스의 멤버 변수와 생성자 만들기
    Context context;
    ArrayList<Memo> arrayList;

    public MemoAdapter(Context context, ArrayList<Memo> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
    //1.어뎁터를 상속 받는다.  //3.만든 뷰 홀더를 적어준다. //4. 오버라이드

    //2.뷰 홀더 클래스를 만든다.
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        TextView txtBody;
        ImageView imageDelete;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtTitle=itemView.findViewById(R.id.txtTitle);
            txtBody=itemView.findViewById(R.id.txtBody);
            imageDelete=itemView.findViewById(R.id.imageDelete);
        }
    }
}

 

 

 

6.상속받은 3개의 메서드 구현

public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {
    //5.이 어댑터 클래스의 멤버 변수와 생성자 만들기
    Context context;
    ArrayList<Memo> memoArrayList;

    public MemoAdapter(Context context, ArrayList<Memo> arrayList) {
        this.context = context;
        this.memoArrayList = arrayList;
    }

    //6.아래 상속받은 3개 함수를 구현한다.
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.memo_row,parent,false);
        return new MemoAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Memo memo = memoArrayList.get(position);
        holder.txtTitle.setText(memo.title);
        holder.txtBody.setText(memo.body);
    }

    @Override
    public int getItemCount() {
        return memoArrayList.size();
    }
    //1.어뎁터를 상속 받는다.  //3.만든 뷰 홀더를 적어준다. //4. 오버라이드

    //2.뷰 홀더 클래스를 만든다.
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView txtTitle;
        TextView txtBody;
        ImageView imageDelete;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtTitle=itemView.findViewById(R.id.txtTitle);
            txtBody=itemView.findViewById(R.id.txtBody);
            imageDelete=itemView.findViewById(R.id.imageDelete);
        }
    }
}

 

1. onCreateViewHolder()

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.memo_row, parent, false);
    return new MemoAdapter.ViewHolder(view);
}
  • 목적: RecyclerView에서 각 항목을 위한 뷰를 생성하는 메서드입니다.
  • onCreateViewHolder()는 RecyclerView가 새로운 아이템 뷰를 필요로 할 때마다 호출됩니다.
  • 이 메서드는 새로운 ViewHolder 객체를 생성하여 RecyclerView.ViewHolder에 해당하는 뷰를 초기화하고 반환합니다.
  • 인자:
    • parent: 뷰가 삽입될 부모 뷰 그룹.
    • viewType: RecyclerView에서 다양한 뷰 유형을 처리할 수 있지만, 여기에서는 사용되지 않음.
  • 반환값: 새로운 뷰 홀더 객체를 반환합니다. 이 뷰 홀더는 각 아이템을 표시하는 데 사용될 레이아웃을 포함하고 있습니다.

2. onBindViewHolder()

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    Memo memo = memoArrayList.get(position);
    holder.txtTitle.setText(memo.title);
    holder.txtBody.setText(memo.body);
}
  • 목적: 각 아이템에 대한 데이터를 뷰 홀더에 바인딩하는 메서드입니다.
  • onBindViewHolder()는 RecyclerView가 화면에 표시할 데이터 항목을 뷰 홀더에 바인딩할 때 호출됩니다. 즉, RecyclerView의 각 항목을 화면에 표시하기 위해 뷰 홀더와 데이터를 연결하는 작업을 합니다.
  • 인자:
    • holder: 데이터를 바인딩할 대상인 ViewHolder 객체입니다. 이 객체는 onCreateViewHolder()에서 생성된 뷰 홀더입니다.
    • position: 바인딩할 데이터의 위치(인덱스)입니다. 이 값에 따라 memoArrayList에서 해당 위치의 데이터를 가져옵니다.
  • 동작:
    • memoArrayList.get(position)을 사용하여 해당 항목의 Memo 객체를 가져오고, 이를 holder의 뷰에 바인딩합니다.
    • 예를 들어, txtTitle에 memo.title 값을, txtBody에 memo.body 값을 설정합니다.

3. getItemCount()

@Override
public int getItemCount() {
    return memoArrayList.size();
}
  • 목적: RecyclerView의 아이템 개수를 반환하는 메서드입니다.
  • 이 메서드는 RecyclerView가 표시해야 할 항목의 개수를 알려줍니다. 이 개수는 RecyclerView가 데이터를 로드하거나 스크롤할 때 중요한 역할을 합니다.
  • 반환값: memoArrayList.size()를 반환하여, 어댑터에 제공된 memoArrayList의 크기(아이템 수)를 반환합니다.

요약

  • onCreateViewHolder()는 새로운 항목 뷰를 생성합니다.
  • onBindViewHolder()는 데이터를 각 항목에 바인딩합니다.
  • getItemCount()는 RecyclerView가 보여야 할 항목의 개수를 반환합니다.

이 세 메서드는 RecyclerView가 데이터를 효율적으로 표시할 수 있도록 도와주는 핵심적인 메서드들입니다.