11package com.fmt.github.base.viewmodel
22
3- import androidx.lifecycle.LiveData
4- import androidx.lifecycle.MutableLiveData
3+ import androidx.lifecycle.asLiveData
54import androidx.lifecycle.viewModelScope
6- import androidx.paging.DataSource
7- import androidx.paging.LivePagedListBuilder
8- import androidx.paging.PageKeyedDataSource
9- import androidx.paging.PagedList
5+ import androidx.paging.*
106import com.fmt.github.config.Configs
11- import kotlinx.coroutines.launch
127
138/* *
149 * 基于Paging封装通用ViewModel
1510 */
16- abstract class BaseLPagingViewModel <M > : BaseViewModel () {
1711
18- private lateinit var mDataSource : PageKeyedDataSource < Int , M >
12+ abstract class BaseLPagingViewModel < M : Any > : BaseViewModel () {
1913
20- val mBoundaryData = MutableLiveData (false )// 控制页面显示状态
21-
22- val refreshState = MutableLiveData (false )
23-
24- val loadMoreState = MutableLiveData (false )
25-
26- private var loadMoreRetry: (() -> Unit )? = null
27-
28- val pagedList: LiveData <PagedList <M >> by lazy {
29- LivePagedListBuilder <Int , M >(
30- object : DataSource .Factory <Int , M >() {
31- override fun create (): DataSource <Int , M > {
32- mDataSource = PageDataSource ()
33- return mDataSource
34- }
35- }, PagedList .Config .Builder ()
36- .setPageSize(Configs .PAGE_SIZE )
37- .setInitialLoadSizeHint(12 )
38- .build()
39- ).build()
14+ val pagedList by lazy {
15+ Pager (config = PagingConfig (pageSize = Configs .PAGE_SIZE , prefetchDistance = 1 )) {
16+ PageDataSource ()
17+ }.flow.asLiveData().cachedIn(viewModelScope)
4018 }
4119
42- // 真正加载数据的来源
43- inner class PageDataSource : PageKeyedDataSource <Int , M >() {
44- override fun loadInitial (
45- params : LoadInitialParams <Int >,
46- callback : LoadInitialCallback <Int , M >
47- ) {
48- viewModelScope.launch {
49- try {
50- val list = getDataList(1 )
51- mBoundaryData.postValue(list.isNotEmpty())
52- callback.onResult(list, null , 2 )
53- mStateLiveData.value = SuccessState
54- refreshState.postValue(false )
55- } catch (e: Exception ) {
56- refreshState.postValue(true )
57- mStateLiveData.value = ErrorState (e.message)
58- }
20+ inner class PageDataSource : PagingSource <Int , M >() {
21+ override suspend fun load (params : LoadParams <Int >): LoadResult <Int , M > {
22+ return try {
23+ val page = params.key ? : 1
24+ val list = getDataList(page)
25+ LoadResult .Page (
26+ data = list,
27+ prevKey = null ,
28+ nextKey = if (list.isEmpty()) null else page + 1
29+ )
30+ } catch (e: Exception ) {
31+ mStateLiveData.value = ErrorState (e.message)
32+ LoadResult .Error (e)
5933 }
6034 }
61-
62- override fun loadAfter (params : LoadParams <Int >, callback : LoadCallback <Int , M >) {
63- viewModelScope.launch {
64- try {
65- val list = getDataList(params.key)
66- callback.onResult(
67- list,
68- params.key + 1
69- )
70- mStateLiveData.value = SuccessState
71- loadMoreState.postValue(false )
72- } catch (e: Exception ) {
73- mStateLiveData.value = ErrorState (e.message)
74- loadMoreState.postValue(true )
75- loadMoreRetry = {
76- // 保存加载更多失败时的场景,防止第一次加载失败后,后续无法再次调用loadAfter
77- loadMoreFail(params, callback)
78- }
79- }
80- }
81- }
82-
83- override fun loadBefore (params : LoadParams <Int >, callback : LoadCallback <Int , M >) {}
84- }
85-
86- fun refresh () {// Paging刷新数据
87- mDataSource.invalidate()
88- }
89-
90- fun loadMoreRetry () {// 加载更多失败重试
91- loadMoreRetry?.invoke()
92- }
93-
94- private fun loadMoreFail (// 加载更多失败时调用
95- params : PageKeyedDataSource .LoadParams <Int >,
96- callback : PageKeyedDataSource .LoadCallback <Int , M >
97- ) {
98- mDataSource.loadAfter(params, callback)
9935 }
10036
10137 abstract suspend fun getDataList (page : Int ): List <M >
10238
103-
10439}
0 commit comments