refactor:优化阅读界面菜单切换page时的高度过渡动画
@fansangg @贡献者
This commit is contained in:
@@ -613,6 +613,7 @@ private fun ReadBookMenuSurface(
|
|||||||
title = stringResource(R.string.read_config),
|
title = stringResource(R.string.read_config),
|
||||||
maxHeight = maxHeight,
|
maxHeight = maxHeight,
|
||||||
bottomPadding = if (extendSurfaceToNavigationBar) navBarHeight else 0.dp,
|
bottomPadding = if (extendSurfaceToNavigationBar) navBarHeight else 0.dp,
|
||||||
|
animateSize = false,
|
||||||
onBack = { onIntent(ReadBookIntent.ReadMenuBack) },
|
onBack = { onIntent(ReadBookIntent.ReadMenuBack) },
|
||||||
) {
|
) {
|
||||||
ReadStyleContent(
|
ReadStyleContent(
|
||||||
@@ -762,6 +763,7 @@ private fun ReadBookMenuRoutePage(
|
|||||||
maxHeight: Dp,
|
maxHeight: Dp,
|
||||||
scrollContent: Boolean = false,
|
scrollContent: Boolean = false,
|
||||||
bottomPadding: Dp = 0.dp,
|
bottomPadding: Dp = 0.dp,
|
||||||
|
animateSize: Boolean = true,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -769,7 +771,7 @@ private fun ReadBookMenuRoutePage(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.heightIn(max = maxHeight)
|
.heightIn(max = maxHeight)
|
||||||
.animateContentSize()
|
.let { if (animateSize) it.animateContentSize() else it }
|
||||||
.padding(top = 16.dp, bottom = 16.dp + bottomPadding),
|
.padding(top = 16.dp, bottom = 16.dp + bottomPadding),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package io.legado.app.ui.book.read.sheet
|
package io.legado.app.ui.book.read.sheet
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -15,20 +18,26 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.res.stringArrayResource
|
import androidx.compose.ui.res.stringArrayResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
@@ -39,7 +48,6 @@ import io.legado.app.ui.book.read.ConfigUpdate
|
|||||||
import io.legado.app.ui.book.read.ReadBookIntent
|
import io.legado.app.ui.book.read.ReadBookIntent
|
||||||
import io.legado.app.ui.widget.components.FontSelectSheet
|
import io.legado.app.ui.widget.components.FontSelectSheet
|
||||||
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
|
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
|
||||||
import org.koin.compose.koinInject
|
|
||||||
import io.legado.app.ui.widget.components.settingItem.TinyClickableSettingItem
|
import io.legado.app.ui.widget.components.settingItem.TinyClickableSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.TinyColorSettingItem
|
import io.legado.app.ui.widget.components.settingItem.TinyColorSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.TinyDropdownSettingItem
|
import io.legado.app.ui.widget.components.settingItem.TinyDropdownSettingItem
|
||||||
@@ -48,6 +56,7 @@ import io.legado.app.ui.widget.components.settingItem.TinySwitchSettingItem
|
|||||||
import io.legado.app.ui.widget.components.tabRow.CardTabRow
|
import io.legado.app.ui.widget.components.tabRow.CardTabRow
|
||||||
import io.legado.app.utils.getCompatColor
|
import io.legado.app.utils.getCompatColor
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koin.compose.koinInject
|
||||||
|
|
||||||
// Color picker IDs
|
// Color picker IDs
|
||||||
private const val COLOR_HEADER = 7
|
private const val COLOR_HEADER = 7
|
||||||
@@ -70,6 +79,9 @@ internal fun HeaderFooterPage(
|
|||||||
val pagerState = rememberPagerState(pageCount = { 3 })
|
val pagerState = rememberPagerState(pageCount = { 3 })
|
||||||
var selectedTab by remember { mutableIntStateOf(0) }
|
var selectedTab by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
|
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
|
||||||
|
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
|
||||||
|
|
||||||
// Header state
|
// Header state
|
||||||
var headerMode by remember { mutableIntStateOf(ReadBookConfig.headerMode) }
|
var headerMode by remember { mutableIntStateOf(ReadBookConfig.headerMode) }
|
||||||
var headerLeft by remember { mutableIntStateOf(ReadBookConfig.tipHeaderLeft) }
|
var headerLeft by remember { mutableIntStateOf(ReadBookConfig.tipHeaderLeft) }
|
||||||
@@ -138,15 +150,31 @@ internal fun HeaderFooterPage(
|
|||||||
selectedTabIndex = selectedTab,
|
selectedTabIndex = selectedTab,
|
||||||
onTabSelected = { index ->
|
onTabSelected = { index ->
|
||||||
selectedTab = index
|
selectedTab = index
|
||||||
scope.launch { pagerState.animateScrollToPage(index) }
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(
|
||||||
|
page = index,
|
||||||
|
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
|
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
|
||||||
)
|
)
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
verticalAlignment = Alignment.Top,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clipToBounds()
|
||||||
|
.pagerHeight(animatedHeight),
|
||||||
) { page ->
|
) { page ->
|
||||||
when (page) {
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.onSizeChanged { size ->
|
||||||
|
pageHeights[page] = size.height
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
when (page) {
|
||||||
0 -> {
|
0 -> {
|
||||||
// Header tab
|
// Header tab
|
||||||
Column(
|
Column(
|
||||||
@@ -372,6 +400,7 @@ internal fun HeaderFooterPage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Color picker
|
// Color picker
|
||||||
ColorPickerSheet(
|
ColorPickerSheet(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package io.legado.app.ui.book.read.sheet
|
package io.legado.app.ui.book.read.sheet
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -8,14 +10,22 @@ import androidx.compose.foundation.pager.HorizontalPager
|
|||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
|
import androidx.compose.ui.layout.layout
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.ui.book.read.ConfigUpdate
|
import io.legado.app.ui.book.read.ConfigUpdate
|
||||||
@@ -44,6 +54,9 @@ fun ReadStyleContent(
|
|||||||
val pagerState = rememberPagerState(pageCount = { 3 })
|
val pagerState = rememberPagerState(pageCount = { 3 })
|
||||||
var currentPage by remember { mutableIntStateOf(0) }
|
var currentPage by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
|
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
|
||||||
|
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
|
||||||
|
|
||||||
LaunchedEffect(pagerState) {
|
LaunchedEffect(pagerState) {
|
||||||
snapshotFlow { pagerState.currentPage }.collect { page ->
|
snapshotFlow { pagerState.currentPage }.collect { page ->
|
||||||
currentPage = page
|
currentPage = page
|
||||||
@@ -57,35 +70,46 @@ fun ReadStyleContent(
|
|||||||
) {
|
) {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
|
verticalAlignment = Alignment.Top,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f, fill = false)
|
.weight(1f, fill = false)
|
||||||
.animateContentSize(),
|
.clipToBounds()
|
||||||
|
.pagerHeight(animatedHeight),
|
||||||
) { page ->
|
) { page ->
|
||||||
when (page) {
|
Box(
|
||||||
0 -> GlobalThemePage(
|
modifier = Modifier
|
||||||
onToggleDayNight = onToggleDayNight,
|
.fillMaxWidth()
|
||||||
onOpenBgTextConfig = onOpenBgTextConfig,
|
.onSizeChanged { size ->
|
||||||
onOpenTextTitle = onOpenTextTitle,
|
pageHeights[page] = size.height
|
||||||
onOpenPaddingConfig = onOpenPaddingConfig,
|
}
|
||||||
onShareLayoutChange = { shareLayout ->
|
) {
|
||||||
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ShareLayout(shareLayout)))
|
when (page) {
|
||||||
},
|
0 -> GlobalThemePage(
|
||||||
onStyleSelect = { index ->
|
onToggleDayNight = onToggleDayNight,
|
||||||
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.StyleSelect(index)))
|
onOpenBgTextConfig = onOpenBgTextConfig,
|
||||||
},
|
onOpenTextTitle = onOpenTextTitle,
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
onOpenPaddingConfig = onOpenPaddingConfig,
|
||||||
onIntent = onIntent,
|
onShareLayoutChange = { shareLayout ->
|
||||||
styleConfig = styleConfig,
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ShareLayout(shareLayout)))
|
||||||
)
|
},
|
||||||
|
onStyleSelect = { index ->
|
||||||
|
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.StyleSelect(index)))
|
||||||
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
|
onIntent = onIntent,
|
||||||
|
styleConfig = styleConfig,
|
||||||
|
)
|
||||||
|
|
||||||
1 -> SystemMenuPage(
|
1 -> SystemMenuPage(
|
||||||
customIcons = readMenuCustomIcons,
|
customIcons = readMenuCustomIcons,
|
||||||
bottomBarButtons = bottomBarButtons,
|
bottomBarButtons = bottomBarButtons,
|
||||||
onIntent = onIntent,
|
onIntent = onIntent,
|
||||||
)
|
)
|
||||||
2 -> HeaderFooterPage(
|
|
||||||
onIntent = onIntent,
|
2 -> HeaderFooterPage(
|
||||||
)
|
onIntent = onIntent,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +124,12 @@ fun ReadStyleContent(
|
|||||||
selectedTabIndex = currentPage,
|
selectedTabIndex = currentPage,
|
||||||
onTabSelected = { index ->
|
onTabSelected = { index ->
|
||||||
if (index < 3) {
|
if (index < 3) {
|
||||||
scope.launch { pagerState.animateScrollToPage(index) }
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(
|
||||||
|
page = index,
|
||||||
|
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
onOpenMoreConfig()
|
onOpenMoreConfig()
|
||||||
}
|
}
|
||||||
@@ -109,3 +138,44 @@ fun ReadStyleContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Modifier.pagerHeight(height: Dp) = this.layout { measurable, constraints ->
|
||||||
|
val placeable = measurable.measure(constraints)
|
||||||
|
val layoutHeight = if (height != Dp.Unspecified) height.roundToPx() else placeable.height
|
||||||
|
layout(placeable.width, layoutHeight) {
|
||||||
|
placeable.placeRelative(0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun rememberPagerAnimatedHeight(
|
||||||
|
pagerState: androidx.compose.foundation.pager.PagerState,
|
||||||
|
pageHeights: Map<Int, Int>
|
||||||
|
): androidx.compose.runtime.State<Dp> {
|
||||||
|
val density = LocalDensity.current
|
||||||
|
return remember(pagerState, density) {
|
||||||
|
derivedStateOf {
|
||||||
|
val pageCount = pagerState.pageCount
|
||||||
|
val position = (pagerState.currentPage + pagerState.currentPageOffsetFraction)
|
||||||
|
.coerceIn(0f, (pageCount - 1).coerceAtLeast(0).toFloat())
|
||||||
|
val floorPage = position.toInt().coerceIn(0, pageCount - 1)
|
||||||
|
val ceilPage = (floorPage + 1).coerceIn(0, pageCount - 1)
|
||||||
|
|
||||||
|
val floorHeight = pageHeights[floorPage] ?: 0
|
||||||
|
val ceilHeight = pageHeights[ceilPage] ?: floorHeight
|
||||||
|
|
||||||
|
val fraction = position - floorPage
|
||||||
|
|
||||||
|
val startHeight = if (floorHeight > 0) floorHeight else (pageHeights.values.firstOrNull() ?: 0)
|
||||||
|
val endHeight = if (ceilHeight > 0) ceilHeight else startHeight
|
||||||
|
|
||||||
|
val interpolated = startHeight + (endHeight - startHeight) * fraction
|
||||||
|
|
||||||
|
if (interpolated > 0) {
|
||||||
|
with(density) { interpolated.toDp() }
|
||||||
|
} else {
|
||||||
|
Dp.Unspecified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package io.legado.app.ui.book.read.sheet
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -24,20 +26,28 @@ import androidx.compose.material.icons.filled.Settings
|
|||||||
import androidx.compose.material.icons.filled.SkipNext
|
import androidx.compose.material.icons.filled.SkipNext
|
||||||
import androidx.compose.material.icons.filled.SkipPrevious
|
import androidx.compose.material.icons.filled.SkipPrevious
|
||||||
import androidx.compose.material.icons.filled.Translate
|
import androidx.compose.material.icons.filled.Translate
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringArrayResource
|
import androidx.compose.ui.res.stringArrayResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
@@ -89,6 +99,9 @@ internal fun SystemMenuPage(
|
|||||||
val pagerState = rememberPagerState(pageCount = { 3 })
|
val pagerState = rememberPagerState(pageCount = { 3 })
|
||||||
var selectedTab by remember { mutableIntStateOf(0) }
|
var selectedTab by remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
|
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
|
||||||
|
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
|
||||||
|
|
||||||
// Shared state for sheets
|
// Shared state for sheets
|
||||||
var showColorPicker by remember { mutableStateOf(false) }
|
var showColorPicker by remember { mutableStateOf(false) }
|
||||||
var colorPickerId by remember { mutableIntStateOf(0) }
|
var colorPickerId by remember { mutableIntStateOf(0) }
|
||||||
@@ -112,39 +125,58 @@ internal fun SystemMenuPage(
|
|||||||
selectedTabIndex = selectedTab,
|
selectedTabIndex = selectedTab,
|
||||||
onTabSelected = { index ->
|
onTabSelected = { index ->
|
||||||
selectedTab = index
|
selectedTab = index
|
||||||
scope.launch { pagerState.animateScrollToPage(index) }
|
scope.launch {
|
||||||
|
pagerState.animateScrollToPage(
|
||||||
|
page = index,
|
||||||
|
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
|
modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
|
||||||
)
|
)
|
||||||
|
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
modifier = Modifier.weight(1f, fill = false),
|
verticalAlignment = Alignment.Top,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f, fill = false)
|
||||||
|
.clipToBounds()
|
||||||
|
.pagerHeight(animatedHeight),
|
||||||
) { page ->
|
) { page ->
|
||||||
when (page) {
|
Box(
|
||||||
0 -> GlobalMenuTab(
|
modifier = Modifier
|
||||||
preferences = preferences,
|
.fillMaxWidth()
|
||||||
readBarStyle = preferences.readBarStyle,
|
.onSizeChanged { size ->
|
||||||
readMenuColorMode = preferences.readMenuColorMode,
|
pageHeights[page] = size.height
|
||||||
onIntent = onIntent,
|
}
|
||||||
onShowColorPicker = { id, initial ->
|
) {
|
||||||
colorPickerId = id
|
when (page) {
|
||||||
colorPickerInitial = initial
|
0 -> GlobalMenuTab(
|
||||||
showColorPicker = true
|
preferences = preferences,
|
||||||
},
|
readBarStyle = preferences.readBarStyle,
|
||||||
)
|
readMenuColorMode = preferences.readMenuColorMode,
|
||||||
1 -> BottomBarTab(
|
onIntent = onIntent,
|
||||||
preferences = preferences,
|
onShowColorPicker = { id, initial ->
|
||||||
customIcons = customIcons,
|
colorPickerId = id
|
||||||
onIntent = onIntent,
|
colorPickerInitial = initial
|
||||||
onShowIconSheet = { showIconSheet = true },
|
showColorPicker = true
|
||||||
onShowColorPicker = { id, initial ->
|
},
|
||||||
colorPickerId = id
|
)
|
||||||
colorPickerInitial = initial
|
|
||||||
showColorPicker = true
|
1 -> BottomBarTab(
|
||||||
},
|
preferences = preferences,
|
||||||
)
|
customIcons = customIcons,
|
||||||
2 -> TopBarTab(preferences = preferences, onIntent = onIntent)
|
onIntent = onIntent,
|
||||||
|
onShowIconSheet = { showIconSheet = true },
|
||||||
|
onShowColorPicker = { id, initial ->
|
||||||
|
colorPickerId = id
|
||||||
|
colorPickerInitial = initial
|
||||||
|
showColorPicker = true
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
2 -> TopBarTab(preferences = preferences, onIntent = onIntent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user