Android Studio

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

ssury94 2025. 3. 5. 21:01

어댑터(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가 데이터를 효율적으로 표시할 수 있도록 도와주는 핵심적인 메서드들입니다.