Android

[Android] RecyclerView와 ListAdapter

도우 2024. 3. 8. 11:05
반응형

이전에 DiffUtil과 AsyncListDiffer에 대해 포스팅하였다. ListAdpater는 이 두개를 기반으로 이루어져 있다.

https://ehdnsdlek.tistory.com/20

 

[Android] RecyclerView의 DiffUtil 알아보기

RecyclerView를 업데이트 하기 위해 초기에는 notifyDataSetChanged()를 호출하여 전체 목록을 업데이트 했지만 이러한 방법은 전체 목록을 재생성하기 때문에 매우 비효율적이다. 이러한 문제를 해결하

ehdnsdlek.tistory.com

 

https://ehdnsdlek.tistory.com/21

 

[Android] RecyclerView의 AsyncListDiffer 알아보기

DiffUtil에 대한 정보는 이전에 포스팅 하였다. 오늘은 AsyncListDiffer에 대해 알아보자 AsyncListDiffer DiffUtil은 메인 스레드에서 작업이 수행되는 경우 성능이 매우 저하된다고 했다. AsyncListDiffer는 DiffUt

ehdnsdlek.tistory.com

이번에는 ListAdapter에 대해서 알아보자


ListAdapter

RecyclerView의 데이터 업데이트를 처리하는 과정에서 DiffUtil의 사용은 성능을 크게 향상시킬 수 있지만, DiffUtil의 사용과 관련된 코드를 매번 작성하는 것은 번거로울 수 있다. 특히 메인 UI 스레드가 아닌 백그라운드 스레드에서 실행하려면 추가적인 작업이 필요하다.

이러한 문제를 해결하기위해 등장한 것이 ListAdapter이다. 개발자가 RecyclerView의 데이터 업데이트를 더 쉽게 관리할 수 있도록 설계되었으며, AsyncListDiffer의 기능을 내장하여 백그라운드 스레드에서 자동으로 연산을 수행한다.

ListAdpater는 RecyclerView.Adapter의 확장으로 AsyncListDiffer를 내부적으로 사용하여 데이터 리스트의 변경 사항을 비동기적으로 처리한다. ListAdapter는 DiffUtil을 사용해 데이터의 차이점을 계산하고, 이 계산을 백그라운드 스레드에서 수행하여 UI 스레드(메인 스레드)의 블로킹을 방지한다.

즉, ListAdapter가 AsyncListDiffer를 사용하는 동시에 AsyncLisDiffer가 내부적으로 DiffUtil을 사용하고 있다.

 

사용법

public abstract class ListAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter

위 코드는 ListAdapter 클래스의 기본 정의이다. ListAdapter는 RecyclerView.Adapter를 상속한 추상 클래스로서
제네릭 타입을 사용하여 유연하게 다양한 데이터 타입(
T)과 ViewHolder(VH)를 처리할 수 있게 설계되어 있다

ListAdapter는 내부적으로 AsyncListDiffer를 사용하여 데이터의 변경을 비동기적으로 처리하기 때문에
이 과정에서 AsyncListDiffer는 제공된 DiffUtil.ItemCallback을 반드시 구현하여야 한다.

DiffUtil.ItemCallback은 두 가지 메서드를 구현해야 한다.

  1. areItemsTheSame(T oldItem, T newItem)
    두 객체가 동일한 항목을 나타내는지 여부를 결정한다.
    일반적으로 고유 식별자를 사용하여 항목이 같은지 비교한다.

  2. areContentsTheSame(T oldItem, T newItem)
    두 객체의 내용이 같은지 여부를 결정한다.
    이 메서드는 areItemsTheSame에서 true를 반환한 항목에 대해서만 호출된다.

 

ListAdapter는 추상클래스로써 AsyncListDiffer를 사용했던 것처럼 RecyclerView의 Adapter를 상속하고, AsyncListDiffer를 만들어서 사용하고 있다. 그렇기에 AsyncListDiffer의 submitList()getCurrentList(), addListListener()도 호출하여 사용할 수 있다.

 

ListAdapter를 사용한 RecyclerViewAdpater는 다음과 같이 작성할 수 있다.

public class MyListAdapter extends ListAdapter<MyItem, MyListAdapter.MyViewHolder> {

    public MyListAdapter(@NonNull DiffUtil.ItemCallback<MyItem> diffCallback) {
        super(diffCallback);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 뷰 홀더 생성 로직
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item_layout, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        // 아이템 바인딩 로직
        MyItem item = getItem(position);
        holder.bind(item);
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        // 뷰 홀더 구현
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            // 초기화 로직
        }

        void bind(MyItem item) {
            // 아이템 데이터로 UI 업데이트
        }
    }

    public static final DiffUtil.ItemCallback<MyItem> DIFF_CALLBACK = new DiffUtil.ItemCallback<MyItem>() {
        @Override
        public boolean areItemsTheSame(@NonNull MyItem oldItem, @NonNull MyItem newItem) {
            // 아이템의 고유성 비교
            return oldItem.getId() == newItem.getId();
        }

        @Override
        public boolean areContentsTheSame(@NonNull MyItem oldItem, @NonNull MyItem newItem) {
            // 아이템의 내용 비교
            return oldItem.equals(newItem);
        }
    };
}
// MyListAdapter 인스턴스를 생성
MyListAdapter myListAdapter = new MyListAdapter(DIFF_CALLBACK);

// RecyclerView에 Adapter 설정
recyclerView.setAdapter(myListAdapter);

// 데이터가 변경되었을 때 submitList 호출
List<MyItem> newItems = fetchData(); // 변경된 데이터 리스트를 가져옴
myListAdapter.submitList(newItems); // 새로운 데이터 리스트를 Adapter에 전달

 

DiffUtil.ItemCallback을 통해 데이터 항목 간의 비교 로직을 정의하고, ListAdapter의 submitList() 메소드를 사용하여 데이터 리스트의 업데이트를 처리하면 된다.

 

정리

ListAdapterAsyncListDiffer의 비동기적 차이점 계산 기능을 내장하고 있다.
데이터 리스트의 변경 사항을 자동으로 처리한다.

따라서, 개발자는 submitList(List<T> list) 메서드를 통해 쉽게 관리할 수 있으며, ListAdapter가 내부적으로 변경 사항을 계산하고 RecyclerView에 반영한다.

 

 

 

반응형