이제 Android 11 개발자 프리뷰를 사용할 수 있습니다. 테스트해 보고 의견을 공유하세요.

페이징된 목록 표시

이 가이드에서는 페이징 라이브러리 개요를 기반으로 특히 정보가 변경될 때 앱의 UI에서 사용자에게 정보 목록을 표시하는 방법을 설명합니다.

뷰 모델에 UI 연결

다음 코드 스니펫에서와 같이 LiveData<PagedList> 인스턴스를 PagedListAdapter에 연결할 수 있습니다.

Kotlin

    private val adapter = ConcertAdapter()
    private lateinit var viewModel: ConcertViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        viewModel = ViewModelProviders.of(this).get(ConcertViewModel::class.java)
        viewModel.concerts.observe(this, Observer { adapter.submitList(it) })
    }
    

자바

    public class ConcertActivity extends AppCompatActivity {
        private ConcertAdapter adapter = new ConcertAdapter();
        private ConcertViewModel viewModel;

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            viewModel = ViewModelProviders.of(this).get(ConcertViewModel.class);
            viewModel.concertList.observe(this, adapter::submitList);
        }
    }
    

데이터 소스가 새로운 PagedList 인스턴스를 제공할 때 활동은 개체를 어댑터로 보냅니다. PagedListAdapter 구현은 업데이트가 계산되는 방식을 정의하며 페이징 및 목록 디핑(Diffing)을 자동으로 처리합니다. 따라서 ViewHolder는 다음과 같이 특정 항목에만 결합해야 합니다.

Kotlin

    class ConcertAdapter() :
            PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
        override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
            val concert: Concert? = getItem(position)

            // Note that "concert" is a placeholder if it's null.
            holder.bindTo(concert)
        }

        companion object {
            private val DIFF_CALLBACK = ... // See Implement the diffing callback section.
        }
    }
    

자바

    public class ConcertAdapter
            extends PagedListAdapter<Concert, ConcertViewHolder> {
        protected ConcertAdapter() {
            super(DIFF_CALLBACK);
        }

        @Override
        public void onBindViewHolder(@NonNull ConcertViewHolder holder,
                int position) {
            Concert concert = getItem(position);

            // Note that "concert" can be null if it's a placeholder.
            holder.bindTo(concert);
        }

        private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK
                = ... // See Implement the diffing callback section.
    }
    

PagedListAdapterPagedList.Callback 개체를 사용하여 페이지 로드 이벤트를 처리합니다. 사용자가 스크롤함에 따라 PagedListAdapterPagedList.loadAround()를 호출하여 DataSource에서 가져와야 하는 항목에 관한 힌트를 기본 PagedList에 제공합니다.

디핑 콜백 구현

다음 샘플은 관련 개체 필드를 비교하는 areContentsTheSame()의 수동 구현을 보여줍니다.

Kotlin

    private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
        // The ID property identifies when items are the same.
        override fun areItemsTheSame(oldItem: Concert, newItem: Concert) =
                oldItem.id == newItem.id

        // If you use the "==" operator, make sure that the object implements
        // .equals(). Alternatively, write custom data comparison logic here.
        override fun areContentsTheSame(
                oldItem: Concert, newItem: Concert) = oldItem == newItem
    }
    

자바

    private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<Concert>() {

        @Override
        public boolean areItemsTheSame(Concert oldItem, Concert newItem) {
            // The ID property identifies when items are the same.
            return oldItem.getId() == newItem.getId();
        }

        @Override
        public boolean areContentsTheSame(Concert oldItem, Concert newItem) {
            // Don't use the "==" operator here. Either implement and use .equals(),
            // or write custom data comparison logic here.
            return oldItem.equals(newItem);
        }
    };
    

어댑터에는 비교 항목의 정의가 포함되어 있으므로 새 PagedList 개체가 로드될 때 어댑터는 이러한 항목의 변경사항을 자동으로 감지합니다. 결과적으로 어댑터는 RecyclerView 개체 내에서 효율적인 항목 애니메이션을 트리거합니다.

다른 어댑터 유형을 사용하여 디핑

자체 어댑터를 제공하는 라이브러리를 사용할 때와 같이 PagedListAdapter에서 상속받지 않기로 선택했다면 AsyncPagedListDiffer 개체로 직접 작업함으로써 페이징 라이브러리 어댑터의 디핑 기능을 여전히 사용할 수 있습니다.

UI에서 자리표시자 제공

앱이 데이터 가져오기를 완료하기 전에 UI에 목록을 표시하려면 자리표시자 목록 항목을 사용자에게 표시할 수 있습니다. PagedList는 데이터가 로드될 때까지 목록 항목 데이터를 null로 표시함으로써 이러한 사례를 처리합니다.

자리표시자 사용 시 다음과 같은 이점이 있습니다.

  • 스크롤바 지원: PagedList는 목록 항목 수를 PagedListAdapter에 제공합니다. 이 정보를 통해 어댑터는 목록의 전체 크기를 포괄하는 스크롤바를 그릴 수 있습니다. 새 페이지가 로드될 때 목록의 크기가 변경되지 않으므로 스크롤바가 이동하지 않습니다.
  • 로드 중 스피너가 필요하지 않음: 목록 크기가 이미 알려져 있으므로 로드 중인 항목이 더 있음을 사용자에게 알릴 필요가 없습니다. 자리표시자 자체가 이러한 정보를 전달합니다.

그러나 자리표시자에 관한 지원을 추가하기 전에 다음 전제 조건에 유의하세요.

  • 셀 수 있는 데이터 세트 필요: Room 지속성 라이브러리DataSource 인스턴스는 항목 수를 효율적으로 계산할 수 있습니다. 그러나 맞춤 로컬 저장소 솔루션 또는 네트워크 전용 데이터 아키텍처를 사용하고 있다면 데이터 세트를 구성하는 항목 수를 파악하는 것은 리소스를 많이 소모하거나 심지어 불가능할 수도 있습니다.
  • 언로드된 항목을 처리하는 데 어댑터 필요: 확장을 위해 목록을 준비하는 데 사용할 어댑터 또는 표시 메커니즘은 null 목록 항목을 처리해야 합니다. 예를 들어 데이터를 ViewHolder에 결합할 때 언로드된 데이터를 보여주기 위해 기본값을 제공해야 합니다.
  • 동일한 크기의 항목 뷰 필요: 소셜 네트워킹 업데이트와 같이 콘텐츠에 따라 목록 항목 크기가 변경될 수 있다면 항목 간 크로스 페이딩은 적합해 보이지 않습니다. 이런 상황에는 자리표시자를 사용하지 않는 것이 좋습니다.

의견 보내기

다음 리소스를 통해 의견을 보내고 아이디어를 공유해 주세요.

Issue Tracker
버그를 수정할 수 있도록 문제를 신고해 주세요.

참고 자료

페이징 라이브러리에 관해 자세히 알아보려면 다음 자료를 참조하세요.

샘플

Codelab

동영상