From a37297a001d31172411c8cd146aa9990c2aed2a6 Mon Sep 17 00:00:00 2001 From: fansangg Date: Sun, 14 Jun 2026 16:30:20 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat=EF=BC=9A=E7=BB=9F=E4=B8=80=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E7=95=8C=E9=9D=A2=E4=BA=8C=E7=BA=A7=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E6=BB=91=E5=8A=A8=E5=8A=A8=E7=94=BB=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/ReadBookMenuBar.kt | 2 +- .../app/ui/book/read/sheet/TextTitleSheet.kt | 63 ++++++++++++++----- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookMenuBar.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookMenuBar.kt index dfb45706c..844c493b9 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookMenuBar.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookMenuBar.kt @@ -669,6 +669,7 @@ private fun ReadBookMenuSurface( title = stringResource(R.string.read_config_text_effects), maxHeight = maxHeight, bottomPadding = if (extendSurfaceToNavigationBar) navBarHeight else 0.dp, + animateSize = false, onBack = { onIntent(ReadBookIntent.ReadMenuBack) }, ) { ReadStyleTextTitleContent( @@ -684,7 +685,6 @@ private fun ReadBookMenuSurface( onOpenFontSelect = { onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.FontSelect)) }, - modifier = Modifier.padding(horizontal = 16.dp), onIntent = onIntent, ) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt b/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt index 5ca6ceb9a..42f2f6408 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt @@ -1,5 +1,8 @@ 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.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -25,12 +28,16 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment 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.stringResource import androidx.compose.ui.text.style.TextAlign @@ -73,19 +80,25 @@ fun ReadStyleTextTitleContent( var selectedTab by remember { mutableIntStateOf(0) } LaunchedEffect(pagerState) { - snapshotFlow { pagerState.settledPage }.collect { selectedTab = it } + snapshotFlow { pagerState.currentPage }.collect { selectedTab = it } } ReadStyleTextTitleContent( tabTitles = tabTitles, selectedTab = selectedTab, - onSelectedTabChange = { selectedTab = it }, pagerState = pagerState, onOpenShadowSet = onOpenShadowSet, onOpenUnderlineConfig = onOpenUnderlineConfig, onOpenHighlightRule = onOpenHighlightRule, 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, onIntent = onIntent, ) @@ -95,7 +108,6 @@ fun ReadStyleTextTitleContent( internal fun ReadStyleTextTitleContent( tabTitles: List, selectedTab: Int, - onSelectedTabChange: (Int) -> Unit, pagerState: PagerState, onOpenShadowSet: () -> Unit, onOpenUnderlineConfig: () -> Unit, @@ -105,6 +117,9 @@ internal fun ReadStyleTextTitleContent( modifier: Modifier = Modifier, onIntent: (ReadBookIntent) -> Unit, ) { + val pageHeights = remember { mutableStateMapOf() } + val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights) + Column( modifier = modifier .fillMaxWidth() @@ -113,26 +128,37 @@ internal fun ReadStyleTextTitleContent( tabTitles = tabTitles, selectedTabIndex = selectedTab, onTabSelected = { index -> - onSelectedTabChange(index) animateToPage(index) }, - modifier = Modifier.padding(bottom = 8.dp), + modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp), ) HorizontalPager( state = pagerState, - modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Top, + modifier = Modifier + .fillMaxWidth() + .clipToBounds() + .pagerHeight(animatedHeight), ) { page -> - when (page) { - 0 -> TextEffectsPage( - onOpenShadowSet = onOpenShadowSet, - onOpenUnderlineConfig = onOpenUnderlineConfig, - onOpenHighlightRule = onOpenHighlightRule, - onOpenFontSelect = onOpenFontSelect, - onIntent = onIntent, - ) + Box( + modifier = Modifier + .fillMaxWidth() + .onSizeChanged { size -> + pageHeights[page] = size.height + } + ) { + when (page) { + 0 -> TextEffectsPage( + onOpenShadowSet = onOpenShadowSet, + onOpenUnderlineConfig = onOpenUnderlineConfig, + onOpenHighlightRule = onOpenHighlightRule, + onOpenFontSelect = onOpenFontSelect, + onIntent = onIntent, + ) - 1 -> LayoutSpacingPage(onIntent = onIntent) - 2 -> TitleSettingsPage(onIntent = onIntent) + 1 -> LayoutSpacingPage(onIntent = onIntent) + 2 -> TitleSettingsPage(onIntent = onIntent) + } } } } @@ -152,6 +178,7 @@ internal fun LayoutSpacingPage( Column( modifier = Modifier .fillMaxWidth() + .padding(horizontal = 16.dp) .verticalScroll(rememberScrollState()), ) { Text( @@ -223,6 +250,7 @@ internal fun TextEffectsPage( Column( modifier = Modifier .fillMaxWidth() + .padding(horizontal = 16.dp) .verticalScroll(rememberScrollState()), ) { Text( @@ -382,6 +410,7 @@ internal fun TitleSettingsPage( Column( modifier = Modifier .fillMaxWidth() + .padding(horizontal = 16.dp) .verticalScroll(rememberScrollState()), ) { TinyDropdownSettingItem( From a99dd4b76524cddb857659f6ef875e384fb597f6 Mon Sep 17 00:00:00 2001 From: fansangg Date: Sun, 14 Jun 2026 17:26:44 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix=EF=BC=9A=E6=BD=9C=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E9=AB=98=E5=BA=A6=E6=B5=8B=E9=87=8F=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=E4=B8=8E=E4=BC=98=E5=8C=96=E5=BB=BA=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/sheet/ReadStyleSheet.kt | 6 ++- .../app/ui/book/read/sheet/TextTitleSheet.kt | 47 ++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/sheet/ReadStyleSheet.kt b/app/src/main/java/io/legado/app/ui/book/read/sheet/ReadStyleSheet.kt index 6d874e8e0..1cb92d9fc 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/sheet/ReadStyleSheet.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/sheet/ReadStyleSheet.kt @@ -140,7 +140,11 @@ 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 + val layoutHeight = if (height != Dp.Unspecified) { + height.roundToPx().coerceIn(constraints.minHeight, constraints.maxHeight) + } else { + placeable.height + } layout(placeable.width, layoutHeight) { placeable.placeRelative(0, 0) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt b/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt index 42f2f6408..371cb116f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/sheet/TextTitleSheet.kt @@ -80,7 +80,7 @@ fun ReadStyleTextTitleContent( var selectedTab by remember { mutableIntStateOf(0) } LaunchedEffect(pagerState) { - snapshotFlow { pagerState.currentPage }.collect { selectedTab = it } + snapshotFlow { pagerState.settledPage }.collect { selectedTab = it } } ReadStyleTextTitleContent( @@ -92,6 +92,7 @@ fun ReadStyleTextTitleContent( onOpenHighlightRule = onOpenHighlightRule, onOpenFontSelect = onOpenFontSelect, animateToPage = { page -> + selectedTab = page scope.launch { pagerState.animateScrollToPage( page = page, @@ -140,25 +141,21 @@ internal fun ReadStyleTextTitleContent( .clipToBounds() .pagerHeight(animatedHeight), ) { page -> - Box( - modifier = Modifier - .fillMaxWidth() - .onSizeChanged { size -> - pageHeights[page] = size.height - } - ) { - when (page) { - 0 -> TextEffectsPage( - onOpenShadowSet = onOpenShadowSet, - onOpenUnderlineConfig = onOpenUnderlineConfig, - onOpenHighlightRule = onOpenHighlightRule, - onOpenFontSelect = onOpenFontSelect, - onIntent = onIntent, - ) + val pageModifier = Modifier.onSizeChanged { size -> + pageHeights[page] = size.height + } + when (page) { + 0 -> TextEffectsPage( + onOpenShadowSet = onOpenShadowSet, + onOpenUnderlineConfig = onOpenUnderlineConfig, + onOpenHighlightRule = onOpenHighlightRule, + onOpenFontSelect = onOpenFontSelect, + modifier = pageModifier, + onIntent = onIntent, + ) - 1 -> LayoutSpacingPage(onIntent = onIntent) - 2 -> TitleSettingsPage(onIntent = onIntent) - } + 1 -> LayoutSpacingPage(modifier = pageModifier, onIntent = onIntent) + 2 -> TitleSettingsPage(modifier = pageModifier, onIntent = onIntent) } } } @@ -168,6 +165,7 @@ internal fun ReadStyleTextTitleContent( @Composable internal fun LayoutSpacingPage( + modifier: Modifier = Modifier, onIntent: (ReadBookIntent) -> Unit, ) { var letterSpacing by remember { mutableFloatStateOf(ReadBookConfig.letterSpacing) } @@ -179,7 +177,8 @@ internal fun LayoutSpacingPage( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) - .verticalScroll(rememberScrollState()), + .verticalScroll(rememberScrollState()) + .then(modifier), ) { Text( text = stringResource(R.string.read_config_body_spacing), @@ -238,6 +237,7 @@ internal fun TextEffectsPage( onOpenUnderlineConfig: () -> Unit, onOpenHighlightRule: () -> Unit, onOpenFontSelect: () -> Unit, + modifier: Modifier = Modifier, onIntent: (ReadBookIntent) -> Unit, ) { var textItalic by remember { mutableStateOf(ReadBookConfig.textItalic) } @@ -251,7 +251,8 @@ internal fun TextEffectsPage( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) - .verticalScroll(rememberScrollState()), + .verticalScroll(rememberScrollState()) + .then(modifier), ) { Text( text = stringResource(R.string.text_typeface), @@ -386,6 +387,7 @@ internal fun TextEffectsPage( @Composable internal fun TitleSettingsPage( + modifier: Modifier = Modifier, onIntent: (ReadBookIntent) -> Unit, ) { var titleMode by remember(ReadBookConfig.titleMode) { mutableIntStateOf(ReadBookConfig.titleMode) } @@ -411,7 +413,8 @@ internal fun TitleSettingsPage( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) - .verticalScroll(rememberScrollState()), + .verticalScroll(rememberScrollState()) + .then(modifier), ) { TinyDropdownSettingItem( title = stringResource(R.string.body_title),