From bea1095b0a177015afa71e005272bbe70ffcfd45 Mon Sep 17 00:00:00 2001 From: HapeLee <63206378+HapeLee@users.noreply.github.com> Date: Sun, 21 Jun 2026 01:20:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=B5=8C=E5=A5=97?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=83=AF=E6=80=A7=E6=BB=91=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/read/sheet/HeaderFooterPage.kt | 11 ++- .../app/ui/book/read/sheet/ReadStyleSheet.kt | 11 ++- .../app/ui/book/read/sheet/SystemMenuPage.kt | 11 ++- .../app/ui/book/read/sheet/TextTitleSheet.kt | 11 ++- .../app/ui/main/bookshelf/BookshelfScreen.kt | 10 ++- .../components/pager/PagerNestedScroll.kt | 75 +++++++++++++------ 6 files changed, 88 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/sheet/HeaderFooterPage.kt b/app/src/main/java/io/legado/app/ui/book/read/sheet/HeaderFooterPage.kt index 41c6edb38..3f1577c73 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/sheet/HeaderFooterPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/sheet/HeaderFooterPage.kt @@ -7,6 +7,7 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -40,7 +41,6 @@ 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.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringArrayResource @@ -59,7 +59,7 @@ import io.legado.app.ui.widget.components.FontFolderState import io.legado.app.ui.widget.components.FontSelectSheet import io.legado.app.ui.widget.components.SectionTitle import io.legado.app.ui.widget.components.dialog.ColorPickerSheet -import io.legado.app.ui.widget.components.pager.rememberConsumeHorizontalPagerNestedScrollConnection +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection 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.TinyDropdownSettingItem @@ -91,7 +91,10 @@ internal fun HeaderFooterPage( val pagerState = rememberPagerState(pageCount = { 3 }) var selectedTab by remember { mutableIntStateOf(0) } var clickScrollCount by remember { mutableIntStateOf(0) } - val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection() + val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) val pageHeights = remember { mutableStateMapOf() } val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights) @@ -221,10 +224,10 @@ internal fun HeaderFooterPage( HorizontalPager( state = pagerState, verticalAlignment = Alignment.Top, + pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .fillMaxWidth() .clipToBounds() - .nestedScroll(childPagerNestedScrollConnection) .pagerHeight(animatedHeight), ) { page -> Box( 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 872bc17b4..cfa817544 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 @@ -2,6 +2,7 @@ package io.legado.app.ui.book.read.sheet import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.tween +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -21,7 +22,6 @@ 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.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.layout import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity @@ -33,7 +33,7 @@ import io.legado.app.ui.book.read.ConfigUpdate import io.legado.app.ui.book.read.ReadBookButtonConfigItem import io.legado.app.ui.book.read.ReadBookIntent import io.legado.app.ui.book.read.ReadBookStyleConfig -import io.legado.app.ui.widget.components.pager.rememberConsumeHorizontalPagerNestedScrollConnection +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection import io.legado.app.ui.widget.components.tabRow.CardTabRow import kotlinx.coroutines.launch @@ -56,7 +56,10 @@ fun ReadStyleContent( val scope = rememberCoroutineScope() val pagerState = rememberPagerState(pageCount = { 2 }) var currentPage by remember { mutableIntStateOf(0) } - val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection() + val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) val pageHeights = remember { mutableStateMapOf() } val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights) @@ -75,10 +78,10 @@ fun ReadStyleContent( HorizontalPager( state = pagerState, verticalAlignment = Alignment.Top, + pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .weight(1f, fill = false) .clipToBounds() - .nestedScroll(childPagerNestedScrollConnection) .pagerHeight(animatedHeight), ) { page -> Box( diff --git a/app/src/main/java/io/legado/app/ui/book/read/sheet/SystemMenuPage.kt b/app/src/main/java/io/legado/app/ui/book/read/sheet/SystemMenuPage.kt index ce54a2c06..9b9c9fae4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/sheet/SystemMenuPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/sheet/SystemMenuPage.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.tween +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -46,7 +47,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.onSizeChanged @@ -69,7 +69,7 @@ import io.legado.app.ui.book.read.ReadBookButtonConfigItem import io.legado.app.ui.book.read.ReadBookIntent import io.legado.app.ui.book.read.ReadBookSheet import io.legado.app.ui.theme.LegadoTheme -import io.legado.app.ui.widget.components.pager.rememberConsumeHorizontalPagerNestedScrollConnection +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection import io.legado.app.ui.widget.components.SectionTitle import io.legado.app.ui.widget.components.dialog.ColorPickerSheet import io.legado.app.ui.widget.components.settingItem.TinyClearColorModeSettingItem @@ -111,7 +111,10 @@ internal fun SystemMenuPage( val pagerState = rememberPagerState(pageCount = { 3 }) var selectedTab by remember { mutableIntStateOf(0) } var clickScrollCount by remember { mutableIntStateOf(0) } - val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection() + val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) val pageHeights = remember { mutableStateMapOf() } val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights) @@ -161,9 +164,9 @@ internal fun SystemMenuPage( HorizontalPager( state = pagerState, verticalAlignment = Alignment.Top, + pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .weight(1f, fill = false) - .nestedScroll(childPagerNestedScrollConnection) .clipToBounds() .pagerHeight(animatedHeight), ) { page -> 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 66785652f..9b9685162 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 @@ -2,6 +2,7 @@ package io.legado.app.ui.book.read.sheet import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.tween +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -35,7 +36,6 @@ 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.input.nestedscroll.nestedScroll import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource @@ -49,7 +49,7 @@ import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.SectionTitle import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.dialog.ColorPickerSheet -import io.legado.app.ui.widget.components.pager.rememberConsumeHorizontalPagerNestedScrollConnection +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection 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.TinyDropdownSettingItem @@ -135,7 +135,10 @@ internal fun ReadStyleTextTitleContent( ) { val pageHeights = remember { mutableStateMapOf() } val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights) - val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection() + val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) Column( modifier = modifier @@ -152,10 +155,10 @@ internal fun ReadStyleTextTitleContent( HorizontalPager( state = pagerState, verticalAlignment = Alignment.Top, + pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .fillMaxWidth() .clipToBounds() - .nestedScroll(childPagerNestedScrollConnection) .pagerHeight(animatedHeight), ) { page -> Box( diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt index d2164e396..8891bfc0e 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt @@ -27,6 +27,7 @@ import androidx.compose.animation.scaleOut import androidx.compose.animation.shrinkVertically import androidx.compose.animation.togetherWith import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -129,7 +130,7 @@ import io.legado.app.ui.widget.components.list.TopFloatingStickyItem import io.legado.app.ui.widget.components.log.AppLogSheet import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem -import io.legado.app.ui.widget.components.pager.rememberConsumeHorizontalPagerNestedScrollConnection +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator import io.legado.app.ui.widget.components.tabRow.AppTabRow import io.legado.app.ui.widget.components.text.AppText @@ -232,7 +233,10 @@ fun BookshelfScreen( initialPage = uiState.selectedGroupIndex.coerceAtLeast(0), pageCount = { uiState.groups.size } ) - val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection() + val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) val latestGroups by rememberUpdatedState(uiState.groups) val latestSelectedGroupId by rememberUpdatedState(uiState.selectedGroupId) @@ -835,9 +839,9 @@ fun BookshelfScreen( } else { HorizontalPager( state = pagerState, + pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .fillMaxSize() - .nestedScroll(childPagerNestedScrollConnection) .then( with(sharedTransitionScope) { if (this != null) Modifier.skipToLookaheadSize() else Modifier diff --git a/app/src/main/java/io/legado/app/ui/widget/components/pager/PagerNestedScroll.kt b/app/src/main/java/io/legado/app/ui/widget/components/pager/PagerNestedScroll.kt index 511cfd14f..b626d6ed6 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/pager/PagerNestedScroll.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/pager/PagerNestedScroll.kt @@ -1,5 +1,8 @@ package io.legado.app.ui.widget.components.pager +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.pager.PagerDefaults +import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.geometry.Offset @@ -7,29 +10,57 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.unit.Velocity -@Composable -fun rememberConsumeHorizontalPagerNestedScrollConnection(): NestedScrollConnection { - return remember { - object : NestedScrollConnection { - override fun onPostScroll( - consumed: Offset, - available: Offset, - source: NestedScrollSource, - ): Offset { - return if (source == NestedScrollSource.Drag && available.x != 0f) { - Offset(x = available.x, y = 0f) - } else { - Offset.Zero - } - } +private class PagerFlingPassThroughConnection( + private val delegate: NestedScrollConnection, + private val orientation: Orientation, +) : NestedScrollConnection { - override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - return if (available.x != 0f) { - Velocity(x = available.x, y = 0f) - } else { - Velocity.Zero - } - } + private fun Velocity.reverseOnOrientation(): Velocity { + return if (orientation == Orientation.Horizontal) { + copy(x = -x, y = 0f) + } else { + copy(x = 0f, y = -y) } } + + override fun onPreScroll( + available: Offset, + source: NestedScrollSource, + ): Offset { + return delegate.onPreScroll(available, source) + } + + override fun onPostScroll( + consumed: Offset, + available: Offset, + source: NestedScrollSource, + ): Offset { + return delegate.onPostScroll(consumed, available, source) + } + + override suspend fun onPreFling(available: Velocity): Velocity { + return delegate.onPreFling(available) + } + + override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { + delegate.onPostFling(consumed, available) + return consumed.reverseOnOrientation() + } +} + +@Composable +fun rememberPagerFlingPassThroughConnection( + state: PagerState, + orientation: Orientation, +): NestedScrollConnection { + val defaultConnection = PagerDefaults.pageNestedScrollConnection( + state = state, + orientation = orientation, + ) + return remember(state, orientation, defaultConnection) { + PagerFlingPassThroughConnection( + delegate = defaultConnection, + orientation = orientation, + ) + } }