mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 10:37:05 +05:30
gradle: upgrade dependencies and sync LazyPagingItems from upstream
This commit is contained in:
parent
eeddc3a3e6
commit
b5c2dc9aaf
5 changed files with 124 additions and 80 deletions
|
@ -18,11 +18,9 @@ import androidx.compose.foundation.lazy.LazyItemScope
|
|||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.paging.CombinedLoadStates
|
||||
import androidx.paging.DifferCallback
|
||||
|
@ -30,7 +28,6 @@ import androidx.paging.ItemSnapshotList
|
|||
import androidx.paging.LoadState
|
||||
import androidx.paging.LoadStates
|
||||
import androidx.paging.NullPaddedList
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.PagingDataDiffer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -38,46 +35,28 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
@Composable
|
||||
fun <T : Any> Flow<PagingData<T>>.collectAsLazyPagingItems(): LazyPagingItems<T> {
|
||||
val lazyPagingItems = remember(this) { LazyPagingItems(this) }
|
||||
|
||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectPagingData() }
|
||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectLoadState() }
|
||||
|
||||
return lazyPagingItems
|
||||
}
|
||||
|
||||
fun <T : Any> LazyListScope.items(
|
||||
items: LazyPagingItems<T>,
|
||||
key: ((item: T) -> Any)? = null,
|
||||
itemContent: @Composable LazyItemScope.(value: T?) -> Unit
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key =
|
||||
if (key == null) null
|
||||
else
|
||||
{ index ->
|
||||
val item = items.peek(index)
|
||||
if (item == null) {
|
||||
PagingPlaceholderKey(index)
|
||||
} else {
|
||||
key(item)
|
||||
}
|
||||
}
|
||||
) { index -> itemContent(items[index]) }
|
||||
}
|
||||
|
||||
class LazyPagingItems<T : Any>
|
||||
/**
|
||||
* The class responsible for accessing the data from a [Flow] of [PagingData]. In order to obtain an
|
||||
* instance of [LazyPagingItems] use the [collectAsLazyPagingItems] extension method of [Flow] with
|
||||
* [PagingData]. This instance can be used by the [items] and [itemsIndexed] methods inside
|
||||
* [LazyListScope] to display data received from the [Flow] of [PagingData].
|
||||
*
|
||||
* @param T the type of value used by [PagingData].
|
||||
*/
|
||||
public class LazyPagingItems<T : Any>
|
||||
internal constructor(
|
||||
/** the [Flow] object which contains a stream of [PagingData] elements. */
|
||||
private val flow: Flow<PagingData<T>>
|
||||
) {
|
||||
private val mainDispatcher = Dispatchers.Main
|
||||
|
||||
/** Contains the latest items list snapshot collected from the [flow]. */
|
||||
private var itemSnapshotList by mutableStateOf(ItemSnapshotList<T>(0, 0, emptyList()))
|
||||
/**
|
||||
* Contains the immutable [ItemSnapshotList] of currently presented items, including any
|
||||
* placeholders if they are enabled. Note that similarly to [peek] accessing the items in a list
|
||||
* will not trigger any loads. Use [get] to achieve such behavior.
|
||||
*/
|
||||
var itemSnapshotList by mutableStateOf(ItemSnapshotList<T>(0, 0, emptyList()))
|
||||
private set
|
||||
|
||||
/** The number of items which can be accessed. */
|
||||
val itemCount: Int
|
||||
|
@ -109,7 +88,6 @@ internal constructor(
|
|||
override suspend fun presentNewList(
|
||||
previousList: NullPaddedList<T>,
|
||||
newList: NullPaddedList<T>,
|
||||
newCombinedLoadStates: CombinedLoadStates,
|
||||
lastAccessedIndex: Int,
|
||||
onListPresentable: () -> Unit
|
||||
): Int? {
|
||||
|
@ -134,23 +112,6 @@ internal constructor(
|
|||
return itemSnapshotList[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state containing the item specified at [index] and notifies Paging of the item
|
||||
* accessed in order to trigger any loads necessary to fulfill [PagingConfig.prefetchDistance].
|
||||
*
|
||||
* @param index the index of the item which should be returned.
|
||||
* @return the state containing the item specified at [index] or null if the item is a placeholder
|
||||
* or [index] is not within the correct bounds.
|
||||
*/
|
||||
@Composable
|
||||
@Deprecated(
|
||||
"Use get() instead. It will return you the value not wrapped into a State",
|
||||
ReplaceWith("this[index]")
|
||||
)
|
||||
fun getAsState(index: Int): State<T?> {
|
||||
return rememberUpdatedState(get(index))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presented item at the specified position, without notifying Paging of the item
|
||||
* access that would normally trigger page loads.
|
||||
|
@ -162,14 +123,6 @@ internal constructor(
|
|||
return itemSnapshotList[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new [ItemSnapshotList] representing the currently presented items, including any
|
||||
* placeholders if they are enabled.
|
||||
*/
|
||||
fun snapshot(): ItemSnapshotList<T> {
|
||||
return itemSnapshotList
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry any failed load requests that would result in a [LoadState.Error] update to this
|
||||
* [LazyPagingItems].
|
||||
|
@ -228,4 +181,100 @@ private val IncompleteLoadState = LoadState.NotLoading(false)
|
|||
private val InitialLoadStates =
|
||||
LoadStates(IncompleteLoadState, IncompleteLoadState, IncompleteLoadState)
|
||||
|
||||
data class PagingPlaceholderKey(private val index: Int)
|
||||
/**
|
||||
* Collects values from this [Flow] of [PagingData] and represents them inside a [LazyPagingItems]
|
||||
* instance. The [LazyPagingItems] instance can be used by the [items] and [itemsIndexed] methods
|
||||
* from [LazyListScope] in order to display the data obtained from a [Flow] of [PagingData].
|
||||
*
|
||||
* @sample androidx.paging.compose.samples.PagingBackendSample
|
||||
*/
|
||||
@Composable
|
||||
public fun <T : Any> Flow<PagingData<T>>.collectAsLazyPagingItems(): LazyPagingItems<T> {
|
||||
val lazyPagingItems = remember(this) { LazyPagingItems(this) }
|
||||
|
||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectPagingData() }
|
||||
LaunchedEffect(lazyPagingItems) { lazyPagingItems.collectLoadState() }
|
||||
|
||||
return lazyPagingItems
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the [LazyPagingItems] and their content to the scope. The range from 0 (inclusive) to
|
||||
* [LazyPagingItems.itemCount] (exclusive) always represents the full range of presentable items,
|
||||
* because every event from [PagingDataDiffer] will trigger a recomposition.
|
||||
*
|
||||
* @sample androidx.paging.compose.samples.ItemsDemo
|
||||
*
|
||||
* @param items the items received from a [Flow] of [PagingData].
|
||||
* @param key a factory of stable and unique keys representing the item. Using the same key for
|
||||
* multiple items in the list is not allowed. Type of the key should be saveable via Bundle on
|
||||
* Android. If null is passed the position in the list will represent the key. When you specify the
|
||||
* key the scroll position will be maintained based on the key, which means if you add/remove items
|
||||
* before the current visible item the item with the given key will be kept as the first visible
|
||||
* one.
|
||||
* @param itemContent the content displayed by a single item. In case the item is `null`, the
|
||||
* [itemContent] method should handle the logic of displaying a placeholder instead of the main
|
||||
* content displayed by an item which is not `null`.
|
||||
*/
|
||||
public fun <T : Any> LazyListScope.items(
|
||||
items: LazyPagingItems<T>,
|
||||
key: ((item: T) -> Any)? = null,
|
||||
itemContent: @Composable LazyItemScope.(value: T?) -> Unit
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key =
|
||||
if (key == null) null
|
||||
else
|
||||
{ index ->
|
||||
val item = items.peek(index)
|
||||
if (item == null) {
|
||||
PagingPlaceholderKey(index)
|
||||
} else {
|
||||
key(item)
|
||||
}
|
||||
}
|
||||
) { index -> itemContent(items[index]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the [LazyPagingItems] and their content to the scope where the content of an item is aware
|
||||
* of its local index. The range from 0 (inclusive) to [LazyPagingItems.itemCount] (exclusive)
|
||||
* always represents the full range of presentable items, because every event from
|
||||
* [PagingDataDiffer] will trigger a recomposition.
|
||||
*
|
||||
* @sample androidx.paging.compose.samples.ItemsIndexedDemo
|
||||
*
|
||||
* @param items the items received from a [Flow] of [PagingData].
|
||||
* @param key a factory of stable and unique keys representing the item. Using the same key for
|
||||
* multiple items in the list is not allowed. Type of the key should be saveable via Bundle on
|
||||
* Android. If null is passed the position in the list will represent the key. When you specify the
|
||||
* key the scroll position will be maintained based on the key, which means if you add/remove items
|
||||
* before the current visible item the item with the given key will be kept as the first visible
|
||||
* one.
|
||||
* @param itemContent the content displayed by a single item. In case the item is `null`, the
|
||||
* [itemContent] method should handle the logic of displaying a placeholder instead of the main
|
||||
* content displayed by an item which is not `null`.
|
||||
*/
|
||||
public fun <T : Any> LazyListScope.itemsIndexed(
|
||||
items: LazyPagingItems<T>,
|
||||
key: ((index: Int, item: T) -> Any)? = null,
|
||||
itemContent: @Composable LazyItemScope.(index: Int, value: T?) -> Unit
|
||||
) {
|
||||
items(
|
||||
count = items.itemCount,
|
||||
key =
|
||||
if (key == null) null
|
||||
else
|
||||
{ index ->
|
||||
val item = items.peek(index)
|
||||
if (item == null) {
|
||||
PagingPlaceholderKey(index)
|
||||
} else {
|
||||
key(index, item)
|
||||
}
|
||||
}
|
||||
) { index -> itemContent(index, items[index]) }
|
||||
}
|
||||
|
||||
private data class PagingPlaceholderKey(private val index: Int)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue