Add dynamic max support

This commit is contained in:
Oleksandr Balan
2023-03-21 17:35:16 +01:00
parent 2c1d7b3ef9
commit 27a3ae2e79
14 changed files with 237 additions and 26 deletions

View File

@@ -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")
}

View File

@@ -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"

View File

@@ -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()

View File

@@ -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])
}
}

View File

@@ -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])
}
}

View File

@@ -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)
}
}

View File

@@ -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])
}

View File

@@ -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])
}
}

View File

@@ -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])
}
}

View File

@@ -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") {