mirror of
https://github.com/fankes/pagecurl-multiplatform.git
synced 2025-09-06 02:35:25 +08:00
Add dynamic max support
This commit is contained in:
@@ -55,4 +55,6 @@ dependencies {
|
||||
implementation("androidx.compose.material:material")
|
||||
implementation("androidx.activity:activity-compose:$activity_version")
|
||||
implementation("com.google.accompanist:accompanist-systemuicontroller:$accompanist_version")
|
||||
implementation("androidx.paging:paging-runtime:$paging_version")
|
||||
implementation("androidx.paging:paging-compose:$paging_compose_version")
|
||||
}
|
||||
|
@@ -14,6 +14,10 @@ enum class Example(
|
||||
"Simple Page Curl",
|
||||
"Basic PageCurl usage"
|
||||
),
|
||||
PagingPageCurl(
|
||||
"PageCurl with lazy paging",
|
||||
"Example how component could be used with paging implementation"
|
||||
),
|
||||
SettingsPageCurl(
|
||||
"Page Curl With Settings",
|
||||
"Showcases how individual interactions can be toggled on / off"
|
||||
|
@@ -31,6 +31,7 @@ import androidx.core.view.WindowCompat
|
||||
import eu.wewox.pagecurl.components.TopBar
|
||||
import eu.wewox.pagecurl.screens.BackPagePageCurlScreen
|
||||
import eu.wewox.pagecurl.screens.InteractionConfigInPageCurlScreen
|
||||
import eu.wewox.pagecurl.screens.PagingPageCurlScreen
|
||||
import eu.wewox.pagecurl.screens.SettingsPageCurlScreen
|
||||
import eu.wewox.pagecurl.screens.ShadowInPageCurlScreen
|
||||
import eu.wewox.pagecurl.screens.SimplePageCurlScreen
|
||||
@@ -61,6 +62,7 @@ class MainActivity : ComponentActivity() {
|
||||
when (selected) {
|
||||
null -> RootScreen(onExampleClick = { example = it })
|
||||
Example.SimplePageCurl -> SimplePageCurlScreen()
|
||||
Example.PagingPageCurl -> PagingPageCurlScreen()
|
||||
Example.SettingsPageCurl -> SettingsPageCurlScreen()
|
||||
Example.StateInPageCurl -> StateInPageCurlScreen()
|
||||
Example.InteractionConfigInPageCurl -> InteractionConfigInPageCurlScreen()
|
||||
|
@@ -53,7 +53,6 @@ fun BackPagePageCurlScreen() {
|
||||
val pages = remember { HowToPageData.backPageHowToPages }
|
||||
var zoomOut by remember { mutableStateOf(false) }
|
||||
val state = rememberPageCurlState(
|
||||
max = pages.size,
|
||||
config = rememberPageCurlConfig(
|
||||
onCustomTap = { size, position ->
|
||||
// When PageCurl is zoomed out then zoom back in
|
||||
@@ -76,7 +75,10 @@ fun BackPagePageCurlScreen() {
|
||||
config = state.config,
|
||||
bottom = { SettingsRow(state.config) },
|
||||
) {
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(
|
||||
count = pages.size,
|
||||
state = state,
|
||||
) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
}
|
||||
|
@@ -48,7 +48,6 @@ fun InteractionConfigInPageCurlScreen() {
|
||||
val pages = remember { HowToPageData.interactionSettingsHowToPages }
|
||||
var zoomOut by remember { mutableStateOf(false) }
|
||||
val state = rememberPageCurlState(
|
||||
max = pages.size,
|
||||
config = rememberPageCurlConfig(
|
||||
onCustomTap = { size, position ->
|
||||
// When PageCurl is zoomed out then zoom back in
|
||||
@@ -71,7 +70,10 @@ fun InteractionConfigInPageCurlScreen() {
|
||||
config = state.config,
|
||||
bottom = { SettingsRow(state.config) },
|
||||
) {
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(
|
||||
count = pages.size,
|
||||
state = state,
|
||||
) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,103 @@
|
||||
@file:OptIn(ExperimentalPageCurlApi::class)
|
||||
|
||||
package eu.wewox.pagecurl.screens
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
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.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import eu.wewox.pagecurl.ExperimentalPageCurlApi
|
||||
import eu.wewox.pagecurl.page.PageCurl
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* PageCurl with lazy paging.
|
||||
* Example how component could be used with paging implementation.
|
||||
*/
|
||||
@Composable
|
||||
fun PagingPageCurlScreen() {
|
||||
val items = rememberPager().collectAsLazyPagingItems()
|
||||
|
||||
val extraItem = items.loadState.append is LoadState.Loading || items.loadState.refresh is LoadState.Loading
|
||||
val count = items.itemCount + (if (extraItem) 1 else 0)
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
PageCurl(count = count) { index ->
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colors.background)
|
||||
) {
|
||||
if (index < items.itemCount) {
|
||||
Text(items[index]?.content.orEmpty())
|
||||
} else {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberPager(): Flow<PagingData<Item>> =
|
||||
remember {
|
||||
Pager(
|
||||
config = PagingConfig(
|
||||
pageSize = 10,
|
||||
prefetchDistance = 3,
|
||||
),
|
||||
pagingSourceFactory = { ItemPagingSource(BackendService()) }
|
||||
).flow
|
||||
}
|
||||
|
||||
private class Item(val content: String)
|
||||
|
||||
private class Response(val items: List<Item>, val nextPageNumber: Int)
|
||||
|
||||
private class BackendService {
|
||||
|
||||
suspend fun searchItems(page: Int): Response {
|
||||
delay(5_000L)
|
||||
return Response(
|
||||
items = List(10) { Item("Content #${page * 10 + it}") },
|
||||
nextPageNumber = page + 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class ItemPagingSource(private val backend: BackendService) : PagingSource<Int, Item>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> =
|
||||
try {
|
||||
val nextPageNumber = params.key ?: 0
|
||||
val response = backend.searchItems(nextPageNumber)
|
||||
LoadResult.Page(
|
||||
data = response.items,
|
||||
prevKey = null, // Only paging forward.
|
||||
nextKey = response.nextPageNumber
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
LoadResult.Error(e)
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<Int, Item>): Int? =
|
||||
state.anchorPosition?.let { anchorPosition ->
|
||||
val anchorPage = state.closestPageToPosition(anchorPosition)
|
||||
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
|
||||
}
|
||||
}
|
@@ -34,7 +34,6 @@ fun SettingsPageCurlScreen() {
|
||||
var showPopup by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
val state = rememberPageCurlState(
|
||||
max = pages.size,
|
||||
config = rememberPageCurlConfig(
|
||||
onCustomTap = { size, position ->
|
||||
// Detect tap somewhere in the center with 64 radius and show popup
|
||||
@@ -48,7 +47,10 @@ fun SettingsPageCurlScreen() {
|
||||
)
|
||||
)
|
||||
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(
|
||||
count = pages.size,
|
||||
state = state,
|
||||
) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
|
||||
|
@@ -40,7 +40,6 @@ fun ShadowInPageCurlScreen() {
|
||||
val pages = remember { HowToPageData.shadowHowToPages }
|
||||
var zoomOut by remember { mutableStateOf(false) }
|
||||
val state = rememberPageCurlState(
|
||||
max = pages.size,
|
||||
config = rememberPageCurlConfig(
|
||||
onCustomTap = { size, position ->
|
||||
// When PageCurl is zoomed out then zoom back in
|
||||
@@ -63,7 +62,10 @@ fun ShadowInPageCurlScreen() {
|
||||
config = state.config,
|
||||
bottom = { SettingsRow(state.config) },
|
||||
) {
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(
|
||||
count = pages.size,
|
||||
state = state,
|
||||
) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
}
|
||||
|
@@ -11,19 +11,17 @@ import eu.wewox.pagecurl.ExperimentalPageCurlApi
|
||||
import eu.wewox.pagecurl.HowToPageData
|
||||
import eu.wewox.pagecurl.components.HowToPage
|
||||
import eu.wewox.pagecurl.page.PageCurl
|
||||
import eu.wewox.pagecurl.page.rememberPageCurlState
|
||||
|
||||
/**
|
||||
* Page Curl With Settings.
|
||||
* Showcases how individual interactions can be toggled on / off.
|
||||
* Simple Page Curl.
|
||||
* Basic PageCurl usage.
|
||||
*/
|
||||
@Composable
|
||||
fun SimplePageCurlScreen() {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
val pages = remember { HowToPageData.simpleHowToPages }
|
||||
val state = rememberPageCurlState(max = pages.size)
|
||||
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(count = pages.size) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,6 @@ fun StateInPageCurlScreen() {
|
||||
val pages = remember { HowToPageData.stateHowToPages }
|
||||
var zoomOut by remember { mutableStateOf(false) }
|
||||
val state = rememberPageCurlState(
|
||||
max = pages.size,
|
||||
config = rememberPageCurlConfig(
|
||||
onCustomTap = { size, position ->
|
||||
// When PageCurl is zoomed out then zoom back in
|
||||
@@ -66,9 +65,12 @@ fun StateInPageCurlScreen() {
|
||||
ZoomOutLayout(
|
||||
zoomOut = zoomOut,
|
||||
config = state.config,
|
||||
bottom = { SettingsRow(state) },
|
||||
bottom = { SettingsRow(pages.size, state) },
|
||||
) {
|
||||
PageCurl(state = state) { index ->
|
||||
PageCurl(
|
||||
count = pages.size,
|
||||
state = state,
|
||||
) { index ->
|
||||
HowToPage(index, pages[index])
|
||||
}
|
||||
}
|
||||
@@ -77,6 +79,7 @@ fun StateInPageCurlScreen() {
|
||||
|
||||
@Composable
|
||||
private fun SettingsRow(
|
||||
max: Int,
|
||||
state: PageCurlState,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
@@ -92,7 +95,7 @@ private fun SettingsRow(
|
||||
}
|
||||
|
||||
SettingsRowButton("Snap to last") {
|
||||
state.snapTo(state.max)
|
||||
state.snapTo(max)
|
||||
}
|
||||
|
||||
SettingsRowButton("Snap forward") {
|
||||
|
Reference in New Issue
Block a user