1 /* 2 * Copyright 2019 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 kotlin.jvm.JvmStatic 21 import kotlinx.coroutines.flow.Flow 22 import kotlinx.coroutines.flow.flowOf 23 24 /** 25 * Container for Paged data from a single generation of loads. 26 * 27 * Each refresh of data (generally either pushed by local storage, or pulled from the network) will 28 * have a separate corresponding [PagingData]. 29 */ 30 public class PagingData<T : Any> 31 internal constructor( 32 internal val flow: Flow<PageEvent<T>>, 33 internal val uiReceiver: UiReceiver, 34 internal val hintReceiver: HintReceiver, 35 36 /** 37 * A lambda returning a nullable PageEvent.Insert containing data which can be accessed and 38 * displayed synchronously without requiring collection. 39 * 40 * For example, the data may be real loaded data that has been cached via [cachedIn]. 41 */ <lambda>null42 private val cachedPageEvent: () -> PageEvent.Insert<T>? = { null } 43 ) { 44 public companion object { 45 internal val NOOP_UI_RECEIVER = 46 object : UiReceiver { retrynull47 override fun retry() {} 48 refreshnull49 override fun refresh() {} 50 } 51 52 internal val NOOP_HINT_RECEIVER = 53 object : HintReceiver { accessHintnull54 override fun accessHint(viewportHint: ViewportHint) {} 55 } 56 57 /** 58 * Create a [PagingData] that immediately displays an empty list of items when submitted to 59 * a presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter] and 60 * dispatches [LoadState.NotLoading] on all LoadStates to the presenter. 61 */ 62 @Suppress("UNCHECKED_CAST") 63 @JvmStatic // Convenience for Java developers. emptynull64 public fun <T : Any> empty(): PagingData<T> = 65 PagingData( 66 flow = 67 flowOf( 68 PageEvent.StaticList( 69 data = listOf(), 70 sourceLoadStates = null, 71 mediatorLoadStates = null, 72 ) 73 ), 74 uiReceiver = NOOP_UI_RECEIVER, 75 hintReceiver = NOOP_HINT_RECEIVER, 76 cachedPageEvent = { 77 PageEvent.Insert.Refresh( 78 pages = 79 listOf( 80 TransformablePage( 81 originalPageOffset = 0, 82 data = listOf(), 83 ) 84 ), 85 placeholdersBefore = 0, 86 placeholdersAfter = 0, 87 sourceLoadStates = LoadStates.IDLE, 88 mediatorLoadStates = null 89 ) 90 } 91 ) 92 93 /** 94 * Create a [PagingData] that immediately displays an empty list of items when submitted to 95 * a presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 96 * 97 * @param sourceLoadStates [LoadStates] of [PagingSource] to pass forward to a presenter. 98 * E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 99 * @param mediatorLoadStates [LoadStates] of [RemoteMediator] to pass forward to a 100 * presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 101 */ 102 @Suppress("UNCHECKED_CAST") 103 @JvmOverloads 104 @JvmStatic // Convenience for Java developers. emptynull105 public fun <T : Any> empty( 106 sourceLoadStates: LoadStates, 107 mediatorLoadStates: LoadStates? = null, 108 ): PagingData<T> = 109 PagingData( 110 flow = 111 flowOf( 112 PageEvent.StaticList( 113 data = listOf(), 114 sourceLoadStates = sourceLoadStates, 115 mediatorLoadStates = mediatorLoadStates, 116 ) 117 ), 118 uiReceiver = NOOP_UI_RECEIVER, 119 hintReceiver = NOOP_HINT_RECEIVER, 120 cachedPageEvent = { 121 PageEvent.Insert.Refresh( 122 pages = 123 listOf( 124 TransformablePage( 125 originalPageOffset = 0, 126 data = listOf(), 127 ) 128 ), 129 placeholdersBefore = 0, 130 placeholdersAfter = 0, 131 sourceLoadStates = sourceLoadStates, 132 mediatorLoadStates = mediatorLoadStates 133 ) 134 } 135 ) 136 137 /** 138 * Create a [PagingData] that immediately displays a static list of items when submitted to 139 * a presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter] and 140 * dispatches [LoadState.NotLoading] on all LoadStates to the presenter. 141 * 142 * @param data Static list of [T] to display. 143 */ 144 @JvmStatic // Convenience for Java developers. fromnull145 public fun <T : Any> from( 146 data: List<T>, 147 ): PagingData<T> = 148 PagingData( 149 flow = 150 flowOf( 151 PageEvent.StaticList( 152 data = data, 153 sourceLoadStates = null, 154 mediatorLoadStates = null, 155 ) 156 ), 157 uiReceiver = NOOP_UI_RECEIVER, 158 hintReceiver = NOOP_HINT_RECEIVER, 159 cachedPageEvent = { 160 PageEvent.Insert.Refresh( 161 pages = listOf(TransformablePage(0, data)), 162 placeholdersBefore = 0, 163 placeholdersAfter = 0, 164 sourceLoadStates = LoadStates.IDLE, 165 mediatorLoadStates = null 166 ) 167 } 168 ) 169 170 /** 171 * Create a [PagingData] that immediately displays a static list of items when submitted to 172 * a presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 173 * 174 * @param data Static list of [T] to display. 175 * @param sourceLoadStates [LoadStates] of [PagingSource] to pass forward to a presenter. 176 * E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 177 * @param mediatorLoadStates [LoadStates] of [RemoteMediator] to pass forward to a 178 * presenter. E.g., [AsyncPagingDataAdapter][androidx.paging.AsyncPagingDataAdapter]. 179 */ 180 @JvmOverloads 181 @JvmStatic // Convenience for Java developers. fromnull182 public fun <T : Any> from( 183 data: List<T>, 184 sourceLoadStates: LoadStates, 185 mediatorLoadStates: LoadStates? = null, 186 ): PagingData<T> = 187 PagingData( 188 flow = 189 flowOf( 190 PageEvent.StaticList( 191 data = data, 192 sourceLoadStates = sourceLoadStates, 193 mediatorLoadStates = mediatorLoadStates, 194 ) 195 ), 196 uiReceiver = NOOP_UI_RECEIVER, 197 hintReceiver = NOOP_HINT_RECEIVER, 198 cachedPageEvent = { 199 PageEvent.Insert.Refresh( 200 pages = listOf(TransformablePage(0, data)), 201 placeholdersBefore = 0, 202 placeholdersAfter = 0, 203 sourceLoadStates = sourceLoadStates, 204 mediatorLoadStates = mediatorLoadStates 205 ) 206 } 207 ) 208 } 209 cachedEventnull210 internal fun cachedEvent(): PageEvent.Insert<T>? = cachedPageEvent() 211 } 212