mirror of
https://github.com/fankes/pagecurl-multiplatform.git
synced 2025-09-06 02:35:25 +08:00
Add PageCurl override with page keys
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
package eu.wewox.pagecurl.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.MaterialTheme
|
||||
@@ -12,7 +14,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.paging.LoadState
|
||||
import androidx.paging.LoadState.Loading
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
@@ -21,6 +23,7 @@ import androidx.paging.PagingState
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import eu.wewox.pagecurl.ExperimentalPageCurlApi
|
||||
import eu.wewox.pagecurl.page.PageCurl
|
||||
import eu.wewox.pagecurl.page.rememberPageCurlState
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@@ -30,23 +33,38 @@ import kotlinx.coroutines.flow.Flow
|
||||
*/
|
||||
@Composable
|
||||
fun PagingPageCurlScreen() {
|
||||
val items = rememberPager().collectAsLazyPagingItems()
|
||||
val startPage = 4 // in range 0..9
|
||||
val startPageOffset = 5 // in range 0..9
|
||||
|
||||
val extraItem = items.loadState.append is LoadState.Loading || items.loadState.refresh is LoadState.Loading
|
||||
val count = items.itemCount + (if (extraItem) 1 else 0)
|
||||
val items = rememberPager(startPage).collectAsLazyPagingItems()
|
||||
|
||||
val loading = with(items.loadState) { refresh is Loading || append is Loading || prepend is Loading }
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
PageCurl(count = count) { index ->
|
||||
if (items.loadState.refresh is Loading) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colors.background)
|
||||
) {
|
||||
if (index < items.itemCount) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
PageCurl(
|
||||
count = items.itemCount,
|
||||
key = { index -> items.peek(index).hashCode() },
|
||||
state = rememberPageCurlState(initialCurrent = startPageOffset),
|
||||
) { index ->
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colors.background)
|
||||
) {
|
||||
Text(items[index]?.content.orEmpty())
|
||||
} else {
|
||||
CircularProgressIndicator()
|
||||
Text(if (loading) "Loading..." else "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,43 +72,47 @@ fun PagingPageCurlScreen() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberPager(): Flow<PagingData<Item>> =
|
||||
private fun rememberPager(startPage: Int): Flow<PagingData<Item>> =
|
||||
remember {
|
||||
Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 10,
|
||||
prefetchDistance = 3,
|
||||
),
|
||||
pagingSourceFactory = { ItemPagingSource(BackendService()) }
|
||||
pagingSourceFactory = { ItemPagingSource(startPage, BackendService()) }
|
||||
).flow
|
||||
}
|
||||
|
||||
private class Item(val content: String)
|
||||
|
||||
private class Response(val items: List<Item>, val nextPageNumber: Int)
|
||||
private class Response(val items: List<Item>, val prePageNumber: Int, val nextPageNumber: Int)
|
||||
|
||||
private class BackendService {
|
||||
|
||||
suspend fun searchItems(page: Int): Response {
|
||||
delay(5_000L)
|
||||
delay(1_000L)
|
||||
return Response(
|
||||
items = List(10) { Item("Content #${page * 10 + it}") },
|
||||
nextPageNumber = page + 1
|
||||
prePageNumber = page - 1,
|
||||
nextPageNumber = page + 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class ItemPagingSource(private val backend: BackendService) : PagingSource<Int, Item>() {
|
||||
private class ItemPagingSource(
|
||||
private val startPage: Int,
|
||||
private val backend: BackendService
|
||||
) : PagingSource<Int, Item>() {
|
||||
|
||||
@Suppress("TooGenericExceptionCaught") // It is only for demo purpose
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> =
|
||||
try {
|
||||
val nextPageNumber = params.key ?: 0
|
||||
val nextPageNumber = params.key ?: startPage
|
||||
val response = backend.searchItems(nextPageNumber)
|
||||
LoadResult.Page(
|
||||
data = response.items,
|
||||
prevKey = null, // Only paging forward.
|
||||
nextKey = response.nextPageNumber
|
||||
prevKey = response.prePageNumber.takeIf { it >= 0 },
|
||||
nextKey = response.nextPageNumber.takeIf { it < 10 }
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
LoadResult.Error(e)
|
||||
|
Reference in New Issue
Block a user