fix: 双击底栏书架滚动当前分组到顶,Pager 惯性传递移至 MainScreen
This commit is contained in:
3 files changed
+48
-12
No files matched your search
@@ -10,6 +10,7 @@ import androidx.compose.animation.SharedTransitionScope
|
|||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.gestures.Orientation
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -44,6 +45,7 @@ import androidx.compose.material3.rememberWideNavigationRailState
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableLongStateOf
|
||||||
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
|
||||||
@@ -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.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.ui.widget.components.navigation.AppNavigationBar
|
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.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.components.text.AppText
|
||||||
import io.legado.app.ui.widget.dialog.TextDialog
|
import io.legado.app.ui.widget.dialog.TextDialog
|
||||||
import io.legado.app.utils.sendToClip
|
import io.legado.app.utils.sendToClip
|
||||||
@@ -189,6 +192,11 @@ fun MainScreen(
|
|||||||
if (index != -1) index else 0
|
if (index != -1) index else 0
|
||||||
}
|
}
|
||||||
val pagerState = rememberPagerState(initialPage = initialPage) { destinations.size }
|
val pagerState = rememberPagerState(initialPage = initialPage) { destinations.size }
|
||||||
|
val pagerNestedScrollConnection = rememberPagerFlingPassThroughConnection(
|
||||||
|
state = pagerState,
|
||||||
|
orientation = Orientation.Horizontal,
|
||||||
|
)
|
||||||
|
var bookshelfScrollToTopRequest by remember { mutableLongStateOf(0L) }
|
||||||
LaunchedEffect(destinations) {
|
LaunchedEffect(destinations) {
|
||||||
if (destinations.isNotEmpty() && pagerState.currentPage !in destinations.indices) {
|
if (destinations.isNotEmpty() && pagerState.currentPage !in destinations.indices) {
|
||||||
pagerState.scrollToPage(destinations.lastIndex)
|
pagerState.scrollToPage(destinations.lastIndex)
|
||||||
@@ -366,6 +374,7 @@ fun MainScreen(
|
|||||||
) {
|
) {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
|
pageNestedScrollConnection = pagerNestedScrollConnection,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.then(
|
.then(
|
||||||
@@ -388,6 +397,7 @@ fun MainScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
MainDestination.Bookshelf -> BookshelfScreen(
|
MainDestination.Bookshelf -> BookshelfScreen(
|
||||||
|
scrollToTopRequest = bookshelfScrollToTopRequest,
|
||||||
onBookClick = { book ->
|
onBookClick = { book ->
|
||||||
context.startActivityForBook(book)
|
context.startActivityForBook(book)
|
||||||
},
|
},
|
||||||
@@ -493,6 +503,16 @@ fun MainScreen(
|
|||||||
pagerState.animateScrollToPage(index)
|
pagerState.animateScrollToPage(index)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onDoubleClick = if (destination == MainDestination.Bookshelf) {
|
||||||
|
{
|
||||||
|
bookshelfScrollToTopRequest++
|
||||||
|
coroutineScope.launch {
|
||||||
|
pagerState.animateScrollToPage(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.defaultMinSize(minWidth = 76.dp)
|
.defaultMinSize(minWidth = 76.dp)
|
||||||
.semantics(mergeDescendants = true) {
|
.semantics(mergeDescendants = true) {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import androidx.compose.animation.scaleOut
|
|||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.gestures.Orientation
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
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.log.AppLogSheet
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
|
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.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.progressIndicator.AppCircularProgressIndicator
|
||||||
import io.legado.app.ui.widget.components.tabRow.AppTabRow
|
import io.legado.app.ui.widget.components.tabRow.AppTabRow
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
@@ -157,6 +155,7 @@ import sh.calvin.reorderable.rememberReorderableLazyGridState
|
|||||||
@Composable
|
@Composable
|
||||||
fun BookshelfScreen(
|
fun BookshelfScreen(
|
||||||
viewModel: BookshelfViewModel = koinViewModel(),
|
viewModel: BookshelfViewModel = koinViewModel(),
|
||||||
|
scrollToTopRequest: Long = 0L,
|
||||||
onBookClick: (BookShelfItem) -> Unit,
|
onBookClick: (BookShelfItem) -> Unit,
|
||||||
onBookLongClick: (book: BookShelfItem, sharedCoverKey: String?) -> Unit,
|
onBookLongClick: (book: BookShelfItem, sharedCoverKey: String?) -> Unit,
|
||||||
onNavigateToSearch: (String) -> Unit,
|
onNavigateToSearch: (String) -> Unit,
|
||||||
@@ -234,10 +233,6 @@ fun BookshelfScreen(
|
|||||||
initialPage = uiState.selectedGroupIndex.coerceAtLeast(0),
|
initialPage = uiState.selectedGroupIndex.coerceAtLeast(0),
|
||||||
pageCount = { uiState.groups.size }
|
pageCount = { uiState.groups.size }
|
||||||
)
|
)
|
||||||
val childPagerNestedScrollConnection = rememberPagerFlingPassThroughConnection(
|
|
||||||
state = pagerState,
|
|
||||||
orientation = Orientation.Horizontal,
|
|
||||||
)
|
|
||||||
val latestGroups by rememberUpdatedState(uiState.groups)
|
val latestGroups by rememberUpdatedState(uiState.groups)
|
||||||
val latestSelectedGroupId by rememberUpdatedState(uiState.selectedGroupId)
|
val latestSelectedGroupId by rememberUpdatedState(uiState.selectedGroupId)
|
||||||
|
|
||||||
@@ -819,6 +814,7 @@ fun BookshelfScreen(
|
|||||||
} else {
|
} else {
|
||||||
if (isUsingStandaloneSearchGroup) {
|
if (isUsingStandaloneSearchGroup) {
|
||||||
BookshelfPage(
|
BookshelfPage(
|
||||||
|
scrollToTopRequest = scrollToTopRequest,
|
||||||
paddingValues = paddingValues,
|
paddingValues = paddingValues,
|
||||||
books = uiState.items,
|
books = uiState.items,
|
||||||
uiState = uiState,
|
uiState = uiState,
|
||||||
@@ -840,7 +836,6 @@ fun BookshelfScreen(
|
|||||||
} else {
|
} else {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
pageNestedScrollConnection = childPagerNestedScrollConnection,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.then(
|
.then(
|
||||||
@@ -866,6 +861,7 @@ fun BookshelfScreen(
|
|||||||
?: uiState.bookshelfSort) == 3 &&
|
?: uiState.bookshelfSort) == 3 &&
|
||||||
isSelectedGroup
|
isSelectedGroup
|
||||||
BookshelfPage(
|
BookshelfPage(
|
||||||
|
scrollToTopRequest = scrollToTopRequest,
|
||||||
paddingValues = paddingValues,
|
paddingValues = paddingValues,
|
||||||
books = books,
|
books = books,
|
||||||
uiState = uiState,
|
uiState = uiState,
|
||||||
@@ -1215,6 +1211,7 @@ private data class BookshelfEditStickySummary(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BookshelfPage(
|
fun BookshelfPage(
|
||||||
|
scrollToTopRequest: Long,
|
||||||
paddingValues: PaddingValues,
|
paddingValues: PaddingValues,
|
||||||
books: ImmutableList<BookUiItem>,
|
books: ImmutableList<BookUiItem>,
|
||||||
uiState: BookshelfUiState,
|
uiState: BookshelfUiState,
|
||||||
@@ -1301,6 +1298,11 @@ fun BookshelfPage(
|
|||||||
val hapticFeedback = LocalHapticFeedback.current
|
val hapticFeedback = LocalHapticFeedback.current
|
||||||
val displayBooks = draggingBooks ?: pendingSavedBooks ?: books
|
val displayBooks = draggingBooks ?: pendingSavedBooks ?: books
|
||||||
val gridState = rememberLazyGridState()
|
val gridState = rememberLazyGridState()
|
||||||
|
LaunchedEffect(scrollToTopRequest, isCurrentPage) {
|
||||||
|
if (scrollToTopRequest > 0L && isCurrentPage) {
|
||||||
|
gridState.animateScrollToItem(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
val reorderableState = rememberReorderableLazyGridState(gridState) { from, to ->
|
val reorderableState = rememberReorderableLazyGridState(gridState) { from, to ->
|
||||||
if (canReorderBooks) {
|
if (canReorderBooks) {
|
||||||
onMoveBook(from.index, to.index, displayBooks)
|
onMoveBook(from.index, to.index, displayBooks)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import androidx.compose.animation.core.Animatable
|
|||||||
import androidx.compose.animation.core.EaseOut
|
import androidx.compose.animation.core.EaseOut
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -77,6 +78,7 @@ val LocalFloatingBottomBarTabScale = staticCompositionLocalOf { { 1f } }
|
|||||||
@Composable
|
@Composable
|
||||||
fun RowScope.FloatingBottomBarItem(
|
fun RowScope.FloatingBottomBarItem(
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onDoubleClick: (() -> Unit)? = null,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable ColumnScope.() -> Unit
|
content: @Composable ColumnScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -84,11 +86,23 @@ fun RowScope.FloatingBottomBarItem(
|
|||||||
Column(
|
Column(
|
||||||
modifier
|
modifier
|
||||||
.clip(ContinuousCapsule)
|
.clip(ContinuousCapsule)
|
||||||
.clickable(
|
.then(
|
||||||
interactionSource = null,
|
if (onDoubleClick != null) {
|
||||||
indication = null,
|
Modifier.combinedClickable(
|
||||||
role = Role.Tab,
|
interactionSource = null,
|
||||||
onClick = onClick
|
indication = null,
|
||||||
|
role = Role.Tab,
|
||||||
|
onClick = onClick,
|
||||||
|
onDoubleClick = onDoubleClick,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Modifier.clickable(
|
||||||
|
interactionSource = null,
|
||||||
|
indication = null,
|
||||||
|
role = Role.Tab,
|
||||||
|
onClick = onClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
|
|||||||
Reference in new issue
Block a user