1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.paging 18 19 import kotlin.jvm.JvmOverloads 20 import kotlinx.coroutines.flow.Flow 21 22 /** 23 * Primary entry point into Paging; constructor for a reactive stream of [PagingData]. The same 24 * Pager instance should be reused within an instance of ViewModel. For example in your ViewModel: 25 * ``` 26 * // create a Pager instance and store to a variable 27 * val pager = Pager( 28 * ... 29 * ) 30 * .flow 31 * .cachedIn(viewModelScope) 32 * ``` 33 * 34 * Each [PagingData] represents a snapshot of the backing paginated data. Updates to the backing 35 * dataset should be represented by a new instance of [PagingData]. 36 * 37 * [PagingSource.invalidate] and calls to [AsyncPagingDataDiffer.refresh] or 38 * [PagingDataAdapter.refresh] will notify [Pager] that the backing dataset has been updated and a 39 * new [PagingData] / [PagingSource] pair will be generated to represent an updated snapshot. 40 * 41 * [PagingData] can be transformed to alter data as it loads, and presented in a `RecyclerView` via 42 * `AsyncPagingDataDiffer` or `PagingDataAdapter`. 43 * 44 * LiveData support is available as an extension property provided by the 45 * `androidx.paging:paging-runtime` artifact. 46 * 47 * RxJava support is available as extension properties provided by the 48 * `androidx.paging:paging-rxjava2` artifact. 49 */ 50 public class Pager<Key : Any, Value : Any> 51 // Experimental usage is propagated to public API via constructor argument. 52 @ExperimentalPagingApi 53 constructor( 54 config: PagingConfig, 55 initialKey: Key? = null, 56 remoteMediator: RemoteMediator<Key, Value>?, 57 pagingSourceFactory: () -> PagingSource<Key, Value> 58 ) { 59 // Experimental usage is internal, so opt-in is allowed here. 60 @JvmOverloads 61 @OptIn(ExperimentalPagingApi::class) 62 public constructor( 63 config: PagingConfig, 64 initialKey: Key? = null, 65 pagingSourceFactory: () -> PagingSource<Key, Value> 66 ) : this(config, initialKey, null, pagingSourceFactory) 67 68 /** 69 * A cold [Flow] of [PagingData], which emits new instances of [PagingData] once they become 70 * invalidated by [PagingSource.invalidate] or calls to [AsyncPagingDataDiffer.refresh] or 71 * [PagingDataAdapter.refresh]. 72 * 73 * To consume this stream as a LiveData or in Rx, you may use the extensions available in the 74 * paging-runtime or paging-rxjava* artifacts. 75 * 76 * NOTE: Instances of [PagingData] emitted by this [Flow] are not re-usable and cannot be 77 * submitted multiple times. This is especially relevant for transforms such as 78 * [Flow.combine][kotlinx.coroutines.flow.combine], which would replay the latest value 79 * downstream. To ensure you get a new instance of [PagingData] for each downstream observer, 80 * you should use the [cachedIn] operator which multicasts the [Flow] in a way that returns a 81 * new instance of [PagingData] with cached data pre-loaded. 82 */ 83 @OptIn(androidx.paging.ExperimentalPagingApi::class) 84 public val flow: Flow<PagingData<Value>> = 85 PageFetcher( 86 pagingSourceFactory = 87 if (pagingSourceFactory is SuspendingPagingSourceFactory<Key, Value>) { 88 pagingSourceFactory::create 89 } else { 90 // cannot pass it as is since it is not a suspend function. Hence, we wrap 91 // it in {} 92 // which means we are calling the original factory inside a suspend function <lambda>null93 { pagingSourceFactory() } 94 }, 95 initialKey = initialKey, 96 config = config, 97 remoteMediator = remoteMediator 98 ) 99 .flow 100 } 101