Paging 3 provides a Paging library based on RecyclerView to handle various functions such as page turning, loading more and refreshing for users, which can effectively optimize the logic of this part of the code.
1. Reference dependencies
implementation "Androidx. The paging: the paging - runtime: 3.0.0 - alpha02"
Copy the code
For details, see Paging 3 Library Overview
2. Load the data source
2.1 Room
When defining the Query statement of the Dao interface, the return type is of type PagingSource, and the second parameter is the data structure of the table. The number of pages per page is controlled by PagingSource. The number of pages per page is defined in PagingConfig.
@Dao
interface CheeseDao {
@Query("SELECT * FROM Cheese ORDER BY name COLLATE NOCASE ASC")
fun allCheesesByName(a): PagingSource<Int, Cheese>
@Insert
fun insert(cheese: Cheese)
@Delete
fun delete(cheese: Cheese)
}
Copy the code
One advantage of using Room is that if you modify the data in Room by insert() or delete(), it will be immediately reflected in the PagingSource, and the data displayed in the interface will change accordingly.
2.2 Customizing data sources
If you do not use Room data directly, but use data from other places, such as network data, you need to customize the PagingSource, which is created as follows:
class PageKeyedSubredditPagingSource(
private val redditApi: RedditApi,
private val subredditName: String
) : PagingSource<String, RedditPost>() {
override suspend fun load(params: LoadParams<String>): LoadResult<String, RedditPost> {
return try {
val data = redditApi.getTop(
subreddit = subredditName,
// The type of the key class is the key in PagingSource< key: Any, Value: Any>. The specific Value is user-defined. Null when first called
after = if (params is Append) params.key else null,
before = if (params is Prepend) params.key else null,
limit = params.loadSize // loadSize indicates the amount of requested data
).data
Page(
data = data.children.map { it.data },
prevKey = data.before,
nextKey = data.after
)
} catch (e: IOException) {
LoadResult.Error(e)
} catch (e: HttpException) {
LoadResult.Error(e)
}
}
}
Copy the code
3. Construct Pager and PagingData
val allCheeses: Flow<PagingData<Cheese>> = Pager(
PagingConfig(
// The size of the data displayed per page. Corresponding to loadparams. loadSize in PagingSource
pageSize = 20.// The pre-refresh distance, how far from the last item to load data
prefetchDistance = 3.// Initialize the number of loads. Default is pageSize * 3
initialLoadSize = 60.// The maximum amount of data that should be stored in memory at one time
maxSize = 200)) {// The data source is required to return an object of type PagingSource
dao.allCheesesByName()
}.flow // Finally construct and external interaction objects, there are two kinds of flow and liveData
Copy the code
4. Construct a custom PagingDataAdapter
class CheeseAdapter : PagingDataAdapter<Cheese, CheeseViewHolder>(diffCallback) {
override fun onBindViewHolder(holder: CheeseViewHolder, position: Int) {
holder.bindTo(getItem(position))
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CheeseViewHolder =
CheeseViewHolder(parent)
companion object {
private val diffCallback = object : DiffUtil.ItemCallback<Cheese>() {
override fun areItemsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Cheese, newItem: Cheese): Boolean =
oldItem == newItem
}
}
}
Copy the code
The PagingDataAdapter only needs to pass in the DiffUtil.itemCallback object in the constructor, without defining and passing data. Then it will associate with PagingData and use the data of PagingData. If you need to get data at a location, use the getItem() method in your class.
In the custom PagingDataAdapter, you only need to implement the onBindViewHolder() and onCreateViewHolder() methods.
5. Link data
val adapter = CheeseAdapter()
recyclerView.adapter = adapter
lifecycleScope.launch {
viewModel.allCheeses.collectLatest { adapter.submitData(it) }
}
Copy the code
Reference article:
Android Jetpack Page Library overview
Jetpack member Paging3 Practice and Source Code Analysis (PART 1)
JetPack Series Paging 3.0 learning