From 88152e0388326299165c9ecb0c72b8c9379bb5cc Mon Sep 17 00:00:00 2001 From: HapeLee <63206378+HapeLee@users.noreply.github.com> Date: Mon, 29 Jun 2026 02:26:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8F=8C=E5=87=BB=E5=BA=95=E6=A0=8F?= =?UTF-8?q?=E4=B9=A6=E6=9E=B6=E6=BB=9A=E5=8A=A8=E5=BD=93=E5=89=8D=E5=88=86?= =?UTF-8?q?=E7=BB=84=E5=88=B0=E9=A1=B6=EF=BC=8CPager=20=E6=83=AF=E6=80=A7?= =?UTF-8?q?=E4=BC=A0=E9=80=92=E7=A7=BB=E8=87=B3=20MainScreen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/main/MainScreen.kt | 20 ++++++++++++++++ .../app/ui/main/bookshelf/BookshelfScreen.kt | 16 +++++++------ .../ui/widget/components/FloatingBottomBar.kt | 24 +++++++++++++++---- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/MainScreen.kt b/app/src/main/java/io/legado/app/ui/main/MainScreen.kt index ac01249b0..a5226c065 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainScreen.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.animation.SharedTransitionScope import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -44,6 +45,7 @@ import androidx.compose.material3.rememberWideNavigationRailState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -85,6 +87,7 @@ 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.navigation.AppNavigationBar import io.legado.app.ui.widget.components.navigation.AppNavigationBarItem +import io.legado.app.ui.widget.components.pager.rememberPagerFlingPassThroughConnection import io.legado.app.ui.widget.components.text.AppText import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.sendToClip @@ -189,6 +192,11 @@ fun MainScreen( if (index != -1) index else 0 } val pagerState = rememberPagerState(initialPage = initialPage) { destinations.size } + val pagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( + state = pagerState, + orientation = Orientation.Horizontal, + ) + var bookshelfScrollToTopRequest by remember { mutableLongStateOf(0L) } LaunchedEffect(destinations) { if (destinations.isNotEmpty() && pagerState.currentPage !in destinations.indices) { pagerState.scrollToPage(destinations.lastIndex) @@ -366,6 +374,7 @@ fun MainScreen( ) { HorizontalPager( state = pagerState, + pageNestedScrollConnection = pagerNestedScrollConnection, modifier = Modifier .fillMaxSize() .then( @@ -388,6 +397,7 @@ fun MainScreen( ) MainDestination.Bookshelf -> BookshelfScreen( + scrollToTopRequest = bookshelfScrollToTopRequest, onBookClick = { book -> context.startActivityForBook(book) }, @@ -493,6 +503,16 @@ fun MainScreen( pagerState.animateScrollToPage(index) } }, + onDoubleClick = if (destination == MainDestination.Bookshelf) { + { + bookshelfScrollToTopRequest++ + coroutineScope.launch { + pagerState.animateScrollToPage(index) + } + } + } else { + null + }, modifier = Modifier .defaultMinSize(minWidth = 76.dp) .semantics(mergeDescendants = true) { 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 fa3735f26..c460367df 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,7 +27,6 @@ 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 @@ -131,7 +130,6 @@ 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.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 @@ -157,6 +155,7 @@ import sh.calvin.reorderable.rememberReorderableLazyGridState @Composable fun BookshelfScreen( viewModel: BookshelfViewModel = koinViewModel(), + scrollToTopRequest: Long = 0L, onBookClick: (BookShelfItem) -> Unit, onBookLongClick: (book: BookShelfItem, sharedCoverKey: String?) -> Unit, onNavigateToSearch: (String) -> Unit, @@ -234,10 +233,6 @@ fun BookshelfScreen( initialPage = uiState.selectedGroupIndex.coerceAtLeast(0), pageCount = { uiState.groups.size } ) - val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection( - state = pagerState, - orientation = Orientation.Horizontal, - ) val latestGroups by rememberUpdatedState(uiState.groups) val latestSelectedGroupId by rememberUpdatedState(uiState.selectedGroupId) @@ -819,6 +814,7 @@ fun BookshelfScreen( } else { if (isUsingStandaloneSearchGroup) { BookshelfPage( + scrollToTopRequest = scrollToTopRequest, paddingValues = paddingValues, books = uiState.items, uiState = uiState, @@ -840,7 +836,6 @@ fun BookshelfScreen( } else { HorizontalPager( state = pagerState, - pageNestedScrollConnection = childPagerNestedScrollConnection, modifier = Modifier .fillMaxSize() .then( @@ -866,6 +861,7 @@ fun BookshelfScreen( ?: uiState.bookshelfSort) == 3 && isSelectedGroup BookshelfPage( + scrollToTopRequest = scrollToTopRequest, paddingValues = paddingValues, books = books, uiState = uiState, @@ -1215,6 +1211,7 @@ private data class BookshelfEditStickySummary( @Composable fun BookshelfPage( + scrollToTopRequest: Long, paddingValues: PaddingValues, books: ImmutableList, uiState: BookshelfUiState, @@ -1301,6 +1298,11 @@ fun BookshelfPage( val hapticFeedback = LocalHapticFeedback.current val displayBooks = draggingBooks ?: pendingSavedBooks ?: books val gridState = rememberLazyGridState() + LaunchedEffect(scrollToTopRequest, isCurrentPage) { + if (scrollToTopRequest > 0L && isCurrentPage) { + gridState.animateScrollToItem(0) + } + } val reorderableState = rememberReorderableLazyGridState(gridState) { from, to -> if (canReorderBooks) { onMoveBook(from.index, to.index, displayBooks) diff --git a/app/src/main/java/io/legado/app/ui/widget/components/FloatingBottomBar.kt b/app/src/main/java/io/legado/app/ui/widget/components/FloatingBottomBar.kt index 6c6d1196f..6e8778288 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/FloatingBottomBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/FloatingBottomBar.kt @@ -9,6 +9,7 @@ import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.EaseOut import androidx.compose.animation.core.spring import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -77,6 +78,7 @@ val LocalFloatingBottomBarTabScale = staticCompositionLocalOf { { 1f } } @Composable fun RowScope.FloatingBottomBarItem( onClick: () -> Unit, + onDoubleClick: (() -> Unit)? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit ) { @@ -84,11 +86,23 @@ fun RowScope.FloatingBottomBarItem( Column( modifier .clip(ContinuousCapsule) - .clickable( - interactionSource = null, - indication = null, - role = Role.Tab, - onClick = onClick + .then( + if (onDoubleClick != null) { + Modifier.combinedClickable( + interactionSource = null, + indication = null, + role = Role.Tab, + onClick = onClick, + onDoubleClick = onDoubleClick, + ) + } else { + Modifier.clickable( + interactionSource = null, + indication = null, + role = Role.Tab, + onClick = onClick, + ) + } ) .fillMaxHeight() .weight(1f)