feat:统一阅读界面二级菜单的滑动动画效果

This commit is contained in:
fansangg
2026-06-14 16:45:19 +08:00
parent 7c9b08d21a
commit a37297a001
2 changed files with 47 additions and 18 deletions
@@ -669,6 +669,7 @@ private fun ReadBookMenuSurface(
title = stringResource(R.string.read_config_text_effects), title = stringResource(R.string.read_config_text_effects),
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) },
) { ) {
ReadStyleTextTitleContent( ReadStyleTextTitleContent(
@@ -684,7 +685,6 @@ private fun ReadBookMenuSurface(
onOpenFontSelect = { onOpenFontSelect = {
onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.FontSelect)) onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.FontSelect))
}, },
modifier = Modifier.padding(horizontal = 16.dp),
onIntent = onIntent, onIntent = onIntent,
) )
} }
@@ -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
@@ -25,12 +28,16 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableFloatStateOf
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.res.stringArrayResource import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -73,19 +80,25 @@ fun ReadStyleTextTitleContent(
var selectedTab by remember { mutableIntStateOf(0) } var selectedTab by remember { mutableIntStateOf(0) }
LaunchedEffect(pagerState) { LaunchedEffect(pagerState) {
snapshotFlow { pagerState.settledPage }.collect { selectedTab = it } snapshotFlow { pagerState.currentPage }.collect { selectedTab = it }
} }
ReadStyleTextTitleContent( ReadStyleTextTitleContent(
tabTitles = tabTitles, tabTitles = tabTitles,
selectedTab = selectedTab, selectedTab = selectedTab,
onSelectedTabChange = { selectedTab = it },
pagerState = pagerState, pagerState = pagerState,
onOpenShadowSet = onOpenShadowSet, onOpenShadowSet = onOpenShadowSet,
onOpenUnderlineConfig = onOpenUnderlineConfig, onOpenUnderlineConfig = onOpenUnderlineConfig,
onOpenHighlightRule = onOpenHighlightRule, onOpenHighlightRule = onOpenHighlightRule,
onOpenFontSelect = onOpenFontSelect, onOpenFontSelect = onOpenFontSelect,
animateToPage = { page -> scope.launch { pagerState.animateScrollToPage(page) } }, animateToPage = { page ->
scope.launch {
pagerState.animateScrollToPage(
page = page,
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)
}
},
modifier = modifier, modifier = modifier,
onIntent = onIntent, onIntent = onIntent,
) )
@@ -95,7 +108,6 @@ fun ReadStyleTextTitleContent(
internal fun ReadStyleTextTitleContent( internal fun ReadStyleTextTitleContent(
tabTitles: List<String>, tabTitles: List<String>,
selectedTab: Int, selectedTab: Int,
onSelectedTabChange: (Int) -> Unit,
pagerState: PagerState, pagerState: PagerState,
onOpenShadowSet: () -> Unit, onOpenShadowSet: () -> Unit,
onOpenUnderlineConfig: () -> Unit, onOpenUnderlineConfig: () -> Unit,
@@ -105,6 +117,9 @@ internal fun ReadStyleTextTitleContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onIntent: (ReadBookIntent) -> Unit, onIntent: (ReadBookIntent) -> Unit,
) { ) {
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
@@ -113,26 +128,37 @@ internal fun ReadStyleTextTitleContent(
tabTitles = tabTitles, tabTitles = tabTitles,
selectedTabIndex = selectedTab, selectedTabIndex = selectedTab,
onTabSelected = { index -> onTabSelected = { index ->
onSelectedTabChange(index)
animateToPage(index) animateToPage(index)
}, },
modifier = Modifier.padding(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(
0 -> TextEffectsPage( modifier = Modifier
onOpenShadowSet = onOpenShadowSet, .fillMaxWidth()
onOpenUnderlineConfig = onOpenUnderlineConfig, .onSizeChanged { size ->
onOpenHighlightRule = onOpenHighlightRule, pageHeights[page] = size.height
onOpenFontSelect = onOpenFontSelect, }
onIntent = onIntent, ) {
) when (page) {
0 -> TextEffectsPage(
onOpenShadowSet = onOpenShadowSet,
onOpenUnderlineConfig = onOpenUnderlineConfig,
onOpenHighlightRule = onOpenHighlightRule,
onOpenFontSelect = onOpenFontSelect,
onIntent = onIntent,
)
1 -> LayoutSpacingPage(onIntent = onIntent) 1 -> LayoutSpacingPage(onIntent = onIntent)
2 -> TitleSettingsPage(onIntent = onIntent) 2 -> TitleSettingsPage(onIntent = onIntent)
}
} }
} }
} }
@@ -152,6 +178,7 @@ internal fun LayoutSpacingPage(
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
) { ) {
Text( Text(
@@ -223,6 +250,7 @@ internal fun TextEffectsPage(
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
) { ) {
Text( Text(
@@ -382,6 +410,7 @@ internal fun TitleSettingsPage(
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
) { ) {
TinyDropdownSettingItem( TinyDropdownSettingItem(