간편한 Paging3 붙여넣기
5931 단어 AndroidPaging 3RecyclerViewtech
공식.https://developer.android.com/topic/libraries/architecture/paging/v3-overview)
Retroffit 통신
@GET("/users/{user}/sample")
suspend fun samplePaging(params: String, page: Int): Response<Model>
여기는 별다른 일을 하지 않았습니다. 평소대로 쓰십시오.리포지토리를 대체할 학급을 준비해야 하기 때문에 리포지토리가 필요 없다.
Paging Source(Repository 대체)
class SamplePagingSource(private val apiParams: String) : PagingSource<Int, String>(), KoinComponent {
private val api: GithubService by inject()
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, String> {
val page = params.key ?: 1
val response = api.samplePaging(apiParams, page).datas
return if (response != null) {
LoadResult.Page(
data = response,
nextKey = page + 1, // 本当はAPIからの戻り値を元に次のページの有無確認など必要
prevKey = page - 1
)
} else {
LoadResult.Page(
data = emptyList(),
prevKey = null,
nextKey = null
)
}
}
}
API Get을 부르는 데 필요한 매개 변수는 작성기 매개 변수를 통해 전달됩니다.private val api: GithubService by inject()
부분적으로 Koin을 사용한 통신(서비스)반에 다니고 있다.
상위 클래스에 대한 Paging Source 지정
<ページングに使うキーの型, データの型>
.이번에는 페이지 정보를 숫자로 표시했기 때문에 Int, 데이터의 유형은 String이다
지정됨
PagingSource<Int, String>
.API에서 데이터를 가져오는 작업을 마쳤을 때
LoadResult.Page
가 반환됩니다.LoadResult.Page.data
Paging Source에서 지정한 유형의 List를 제공합니다.LoadResult.Page.prevKey
이전 페이지의 키LoadResult.Page.nextKey
다음 페이지의 키를 클릭하고 를 클릭합니다.
※ (전면/하면) 페이지가 없을 때null을 제출합니다.
또 오류를 내고 싶으면 반납
LoadResult.Error(e)
할 수 있다.ViewModel
val samplePagingFlow: Flow<PagingData<String>> = Pager(
PagingConfig(pageSize = 10, initialLoadSize = 10)
) {
SamplePagingSource("params")
}.flow.cachedIn(viewModelScope)
Paging Source를 Flow로 읽습니다.Adapter
일반 ReyclearView어댑터와의 차이점은
차이가 많지 않다.
Fragment
class SampleAdapter : PagingDataAdapter<String, SampleAdapter.ViewHolder>(diffCallback) {
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding.title = getItem(position)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ViewSampleBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
class ViewHolder(val binding: ViewSampleBinding) : RecyclerView.ViewHolder(binding.root)
companion object {
val diffCallback = object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
// 本当はユニークなidなどで比較する
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}
}
}
}
ViewModel로 Flow화한 PagingSource가 변경되었을 때 Adapter#submitData를 진행한다.※ 평소와 마찬가지로 RecyclearView.어댑터 및 LayoutManager를 지정하십시오.
이렇게 하면 Paging 프로세스를 수행할 수 있습니다.
추가(로드 중 진행 상태를 표시하려는 경우)
Layout
viewLifecycleOwner.lifecycleScope.launch {
viewModel.samplePagingFlow.collectLatest { pagingData ->
sampleAdapter.submitData(pagingData)
}
}
진행률 막대만 설정할 레이아웃을 준비합니다.LoadStateAdapter
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
LoadState 어댑터 준비(RecyclearView.어댑터와 같은 내용)progress.visibility = if (loadState is LoadState.Loading) View.VISIBLE else View.GONE
에서 진행 상태 표시/숨기기를 전환합니다.Fragment
class SampleLoadStateAdapter : LoadStateAdapter<ViewHolder>() {
override fun onBindViewHolder(holder: LoadStateViewHolder, loadState: LoadState) {
val progress = holder.itemView.findViewById<ProgressBar>(R.id.progress)
progress.visibility = if (loadState is LoadState.Loading) View.VISIBLE else View.GONE
}
override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState) =
LoadStateViewHolder(parent)
class ViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.view_sample_load_state, parent, false)
)
}
Fragment에서 withLoadState Footer만 지정하면 로드 여부를 판정할 수 있습니다.LoadState 어댑터가 지정한 로드에서 처리를 수행합니다.
오류 시 다시 시도할 수 있으며 공식 샘플 앱도 소개되어 있습니다.
※ 집필할 때 보고 싶으면 404...
Reference
이 문제에 관하여(간편한 Paging3 붙여넣기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/sobya/articles/9e55f1effc520880d306텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)