paging3实现RecyclerView二级列表
时间: 2023-11-16 20:06:38 浏览: 152
Paging3 是一个用于 Android 的分页库,它可以帮助你更加容易地实现分页功能。
要在 RecyclerView 中实现二级列表,你需要做以下几个步骤:
1. 创建一个数据类,用于保存二级列表的数据。
```kotlin
data class SubItem(val name: String, val description: String)
data class Item(val name: String, val subItems: List<SubItem>)
```
2. 创建一个 RecyclerViewAdapter 类,继承自 PagingDataAdapter。
```kotlin
class MyAdapter :
PagingDataAdapter<Item, RecyclerView.ViewHolder>(ItemDiffCallback) {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
if (item != null) {
when (holder) {
is ItemViewHolder -> holder.bind(item)
is SubItemViewHolder -> holder.bind(item.subItems[position - 1])
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_VIEW_TYPE -> ItemViewHolder.create(parent)
SUB_ITEM_VIEW_TYPE -> SubItemViewHolder.create(parent)
else -> throw IllegalArgumentException("unknown view type $viewType")
}
}
override fun getItemViewType(position: Int): Int {
return if (position == 0) {
ITEM_VIEW_TYPE
} else {
SUB_ITEM_VIEW_TYPE
}
}
companion object {
private const val ITEM_VIEW_TYPE = 0
private const val SUB_ITEM_VIEW_TYPE = 1
}
}
```
3. 创建 ViewHolder 类。
```kotlin
class ItemViewHolder private constructor(private val binding: ItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Item) {
binding.name.text = item.name
}
companion object {
fun create(parent: ViewGroup): ItemViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemBinding.inflate(layoutInflater, parent, false)
return ItemViewHolder(binding)
}
}
}
class SubItemViewHolder private constructor(private val binding: SubItemBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(subItem: SubItem) {
binding.name.text = subItem.name
binding.description.text = subItem.description
}
companion object {
fun create(parent: ViewGroup): SubItemViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = SubItemBinding.inflate(layoutInflater, parent, false)
return SubItemViewHolder(binding)
}
}
}
```
4. 创建 DiffCallback。
```kotlin
object ItemDiffCallback : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.name == newItem.name
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
}
```
5. 在 Activity 中初始化 RecyclerView 和 Paging3。
```kotlin
class MyActivity : AppCompatActivity() {
private val viewModel by viewModels<MyViewModel>()
private val adapter = MyAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerView.adapter = adapter
lifecycleScope.launch {
viewModel.flow.collectLatest { pagingData ->
adapter.submitData(pagingData)
}
}
}
}
```
6. 在 ViewModel 中创建数据源。
```kotlin
class MyViewModel : ViewModel() {
private val repository = MyRepository()
val flow = Pager(PagingConfig(pageSize = 10)) {
repository.getPager()
}.flow
}
```
7. 在 Repository 中创建数据源。
```kotlin
class MyRepository {
fun getPager(): PagingSource<Int, Item> {
return object : PagingSource<Int, Item>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {
val page = params.key ?: 1
val items = mutableListOf<Item>()
// TODO: load data from API or database
return LoadResult.Page(
data = items,
prevKey = if (page == 1) null else page - 1,
nextKey = if (items.isEmpty()) null else page + 1
)
}
override fun getRefreshKey(state: PagingState<Int, Item>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
}
}
}
```
这样就完成了 RecyclerView 的二级列表实现。通过 Paging3,你可以更加方便地实现分页功能,同时也可以更好地管理数据源。
阅读全文