fix: 修复分页嵌套滑动冲突

This commit is contained in:
HapeLee
2026-06-21 00:43:48 +08:00
parent b8192724c3
commit 43d2b616f6
6 changed files with 54 additions and 0 deletions
@@ -40,6 +40,7 @@ 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
@@ -58,6 +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.settingItem.TinyClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.TinyColorSettingItem
import io.legado.app.ui.widget.components.settingItem.TinyDropdownSettingItem
@@ -89,6 +91,7 @@ internal fun HeaderFooterPage(
val pagerState = rememberPagerState(pageCount = { 3 })
var selectedTab by remember { mutableIntStateOf(0) }
var clickScrollCount by remember { mutableIntStateOf(0) }
val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection()
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
@@ -221,6 +224,7 @@ internal fun HeaderFooterPage(
modifier = Modifier
.fillMaxWidth()
.clipToBounds()
.nestedScroll(childPagerNestedScrollConnection)
.pagerHeight(animatedHeight),
) { page ->
Box(
@@ -21,6 +21,7 @@ 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
@@ -32,6 +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.tabRow.CardTabRow
import kotlinx.coroutines.launch
@@ -54,6 +56,7 @@ fun ReadStyleContent(
val scope = rememberCoroutineScope()
val pagerState = rememberPagerState(pageCount = { 2 })
var currentPage by remember { mutableIntStateOf(0) }
val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection()
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
@@ -75,6 +78,7 @@ fun ReadStyleContent(
modifier = Modifier
.weight(1f, fill = false)
.clipToBounds()
.nestedScroll(childPagerNestedScrollConnection)
.pagerHeight(animatedHeight),
) { page ->
Box(
@@ -46,6 +46,7 @@ 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
@@ -68,6 +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.SectionTitle
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
import io.legado.app.ui.widget.components.settingItem.TinyClearColorModeSettingItem
@@ -109,6 +111,7 @@ internal fun SystemMenuPage(
val pagerState = rememberPagerState(pageCount = { 3 })
var selectedTab by remember { mutableIntStateOf(0) }
var clickScrollCount by remember { mutableIntStateOf(0) }
val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection()
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
@@ -160,6 +163,7 @@ internal fun SystemMenuPage(
verticalAlignment = Alignment.Top,
modifier = Modifier
.weight(1f, fill = false)
.nestedScroll(childPagerNestedScrollConnection)
.clipToBounds()
.pagerHeight(animatedHeight),
) { page ->
@@ -35,6 +35,7 @@ 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
@@ -48,6 +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.settingItem.TinyClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.TinyColorSettingItem
import io.legado.app.ui.widget.components.settingItem.TinyDropdownSettingItem
@@ -133,6 +135,7 @@ internal fun ReadStyleTextTitleContent(
) {
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
val animatedHeight by rememberPagerAnimatedHeight(pagerState, pageHeights)
val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection()
Column(
modifier = modifier
@@ -152,6 +155,7 @@ internal fun ReadStyleTextTitleContent(
modifier = Modifier
.fillMaxWidth()
.clipToBounds()
.nestedScroll(childPagerNestedScrollConnection)
.pagerHeight(animatedHeight),
) { page ->
Box(
@@ -129,6 +129,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.progressIndicator.AppCircularProgressIndicator
import io.legado.app.ui.widget.components.tabRow.AppTabRow
import io.legado.app.ui.widget.components.text.AppText
@@ -231,6 +232,7 @@ fun BookshelfScreen(
initialPage = uiState.selectedGroupIndex.coerceAtLeast(0),
pageCount = { uiState.groups.size }
)
val childPagerNestedScrollConnection = rememberConsumeHorizontalPagerNestedScrollConnection()
val latestGroups by rememberUpdatedState(uiState.groups)
val latestSelectedGroupId by rememberUpdatedState(uiState.selectedGroupId)
@@ -835,6 +837,7 @@ fun BookshelfScreen(
state = pagerState,
modifier = Modifier
.fillMaxSize()
.nestedScroll(childPagerNestedScrollConnection)
.then(
with(sharedTransitionScope) {
if (this != null) Modifier.skipToLookaheadSize() else Modifier
@@ -0,0 +1,35 @@
package io.legado.app.ui.widget.components.pager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
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
}
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
return if (available.x != 0f) {
Velocity(x = available.x, y = 0f)
} else {
Velocity.Zero
}
}
}
}
}