From 7ca241e1ae3913c3708cb9474357dea29b01e466 Mon Sep 17 00:00:00 2001 From: fansan Date: Wed, 1 Jul 2026 23:34:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=BC=80=E4=BA=86=E6=8A=98=E5=8F=A0?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E6=A0=8F=E5=90=8E=E4=B8=8B=E6=8B=89=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20(#1629)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/explore/ExploreShowScreen.kt | 3 +- .../ui/book/import/local/ImportBookScreen.kt | 6 +++- .../ui/book/import/remote/RemoteBookScreen.kt | 7 +++- .../legado/app/ui/book/info/BookInfoScreen.kt | 3 +- .../app/ui/main/bookshelf/BookshelfScreen.kt | 3 +- .../io/legado/app/ui/main/home/HomeScreen.kt | 1 + .../ui/widget/components/AppPullToRefresh.kt | 34 +++++++++++++------ .../ui/widget/components/list/ListScaffold.kt | 4 +-- .../topbar/GlassMediumFlexibleTopAppBar.kt | 10 ++++-- 9 files changed, 51 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt index 6e7974255..76af1c62e 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt @@ -288,7 +288,8 @@ fun ExploreShowScreen( modifier = Modifier.fillMaxSize(), isRefreshing = state.isRefreshing, onRefresh = { viewModel.onIntent(ExploreShowIntent.Refresh) }, - topPadding = paddingValues.calculateTopPadding() + topPadding = paddingValues.calculateTopPadding(), + scrollBehavior = scrollBehavior ) { Crossfade( targetState = isGridMode, diff --git a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt index 901a7f04d..ded0c1193 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt @@ -71,6 +71,7 @@ import io.legado.app.ui.widget.components.list.ListScaffold import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator import io.legado.app.ui.widget.components.text.AppText +import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults import io.legado.app.ui.widget.components.topbar.TopBarActionButton import io.legado.app.utils.ConvertUtils import io.legado.app.utils.startActivityForBook @@ -98,9 +99,11 @@ private fun ImportBookContent( onDeleteSelection: () -> Unit, onItemClick: (ImportBook) -> Unit ) { + val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() ListScaffold( title = state.pathNames.lastOrNull() ?: stringResource(R.string.local_book), state = state, + scrollBehavior = scrollBehavior, onBackClick = onBackClick, onSearchToggle = onSearchToggle, onSearchQueryChange = onSearchQueryChange, @@ -197,7 +200,8 @@ private fun ImportBookContent( .padding(paddingValues), isRefreshing = state.isLoading, onRefresh = onScanFolder, - topPadding = paddingValues.calculateTopPadding() + topPadding = paddingValues.calculateTopPadding(), + scrollBehavior = scrollBehavior ) { when { state.items.isEmpty() && state.isLoading -> { diff --git a/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt b/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt index c068a5f92..9f63e9587 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt @@ -87,6 +87,7 @@ import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet import io.legado.app.ui.widget.components.progressIndicator.AppCircularProgressIndicator import io.legado.app.ui.widget.components.text.AppText +import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults import io.legado.app.ui.widget.components.topbar.TopBarActionButton import io.legado.app.utils.ConvertUtils import io.legado.app.utils.startActivityForBook @@ -209,6 +210,8 @@ fun RemoteBookScreen( } } + val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() + LaunchedEffect(viewModel) { viewModel.dispatch(RemoteBookIntent.Initialize) viewModel.effects.collect { effect -> @@ -252,6 +255,7 @@ fun RemoteBookScreen( ListScaffold( title = "远程书籍", state = uiState, + scrollBehavior = scrollBehavior, onBackClick = onBackClick, onSearchToggle = { viewModel.dispatch(RemoteBookIntent.SearchToggle(it)) }, onSearchQueryChange = { viewModel.dispatch(RemoteBookIntent.SearchChange(it)) }, @@ -322,7 +326,8 @@ fun RemoteBookScreen( .padding(paddingValues), isRefreshing = uiState.isLoading, onRefresh = { viewModel.dispatch(RemoteBookIntent.Refresh) }, - topPadding = paddingValues.calculateTopPadding() + topPadding = paddingValues.calculateTopPadding(), + scrollBehavior = scrollBehavior ) { if (uiState.items.isEmpty()) { if (uiState.isLoading) { diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt index a30b3e97a..7c2616a22 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt @@ -193,7 +193,8 @@ private fun BookInfoScreenContent( modifier = Modifier.fillMaxSize(), isRefreshing = state.isTocLoading, onRefresh = { onIntent(BookInfoIntent.MenuAction(BookInfoMenuAction.Refresh)) }, - topPadding = paddingValues.calculateTopPadding() + topPadding = paddingValues.calculateTopPadding(), + scrollBehavior = scrollBehavior ) { LazyColumn( state = listState, 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 0fa9c8e3d..20098219d 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 @@ -717,7 +717,8 @@ fun BookshelfScreen( isRefreshing = uiState.isRefreshing, onRefresh = { viewModel.refreshBooks(uiState.items) }, enabled = pullToRefreshEnabled, - topPadding = paddingValues.calculateTopPadding() + topPadding = paddingValues.calculateTopPadding(), + scrollBehavior = scrollBehavior ) { folderTransition.AnimatedContent( transitionSpec = { diff --git a/app/src/main/java/io/legado/app/ui/main/home/HomeScreen.kt b/app/src/main/java/io/legado/app/ui/main/home/HomeScreen.kt index 3d64c7ef7..1c33fe9d9 100644 --- a/app/src/main/java/io/legado/app/ui/main/home/HomeScreen.kt +++ b/app/src/main/java/io/legado/app/ui/main/home/HomeScreen.kt @@ -452,6 +452,7 @@ fun HomeScreen( isRefreshing = homepageState.isRefreshing, onRefresh = onRefreshHomepage, modifier = Modifier.fillMaxSize(), + scrollBehavior = scrollBehavior, ) { BoxWithConstraints(modifier = Modifier.fillMaxSize()) { val dashboardScrollState = rememberScrollState() diff --git a/app/src/main/java/io/legado/app/ui/widget/components/AppPullToRefresh.kt b/app/src/main/java/io/legado/app/ui/widget/components/AppPullToRefresh.kt index b952821b0..79e2b3b14 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/AppPullToRefresh.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/AppPullToRefresh.kt @@ -21,6 +21,9 @@ import androidx.compose.ui.unit.dp import io.legado.app.R import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.ThemeResolver +import io.legado.app.ui.widget.components.topbar.GlassTopAppBarScrollBehavior +import io.legado.app.ui.widget.components.topbar.M3GlassScrollBehavior +import io.legado.app.ui.widget.components.topbar.MiuixGlassScrollBehavior import kotlinx.coroutines.delay import top.yukonga.miuix.kmp.basic.PullToRefresh as MiuixPullToRefresh import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState as miuixRememberPullToRefreshState @@ -33,6 +36,7 @@ fun AppPullToRefresh( modifier: Modifier = Modifier, enabled: Boolean = true, topPadding: Dp = 0.dp, + scrollBehavior: GlassTopAppBarScrollBehavior? = null, content: @Composable () -> Unit, ) { if (ThemeResolver.isMiuixEngine(composeEngine)) { @@ -58,6 +62,7 @@ fun AppPullToRefresh( modifier = modifier, contentPadding = PaddingValues(top = topPadding + 16.dp), pullToRefreshState = miuixRememberPullToRefreshState(), + topAppBarScrollBehavior = (scrollBehavior as? MiuixGlassScrollBehavior)?.miuixBehavior, refreshTexts = listOf( stringResource(R.string.pull_to_refresh), stringResource(R.string.release_to_refresh), @@ -69,22 +74,31 @@ fun AppPullToRefresh( } } else { val state = rememberPullToRefreshState() + val actualEnabled = enabled && ( + isRefreshing || + state.distanceFraction > 0f || + scrollBehavior == null || + if (scrollBehavior is M3GlassScrollBehavior) { + val appbarState = scrollBehavior.m3Behavior.state + (appbarState.heightOffsetLimit == 0f || appbarState.heightOffset >= 0f) && appbarState.contentOffset >= 0f + } else { + scrollBehavior.collapsedFraction <= 0f + } + ) PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, - enabled = enabled, + enabled = actualEnabled, indicator = { - if (enabled) { - PullToRefreshDefaults.LoadingIndicator( - state = state, - isRefreshing = isRefreshing, - modifier = Modifier - .padding(top = topPadding) - .align(Alignment.TopCenter), - ) - } + PullToRefreshDefaults.LoadingIndicator( + state = state, + isRefreshing = isRefreshing, + modifier = Modifier + .padding(top = topPadding) + .align(Alignment.TopCenter), + ) } ) { content() diff --git a/app/src/main/java/io/legado/app/ui/widget/components/list/ListScaffold.kt b/app/src/main/java/io/legado/app/ui/widget/components/list/ListScaffold.kt index 569b54ce7..f0c6ac3f2 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/list/ListScaffold.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/list/ListScaffold.kt @@ -75,10 +75,10 @@ fun ListScaffold( }, snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }, contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, + scrollBehavior: GlassTopAppBarScrollBehavior? = null, content: @Composable (PaddingValues) -> Unit ) { - val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() - + val scrollBehavior = scrollBehavior ?: GlassTopAppBarDefaults.defaultScrollBehavior() AppScaffold( modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), snackbarHost = { diff --git a/app/src/main/java/io/legado/app/ui/widget/components/topbar/GlassMediumFlexibleTopAppBar.kt b/app/src/main/java/io/legado/app/ui/widget/components/topbar/GlassMediumFlexibleTopAppBar.kt index 2596b43da..7938ce6fe 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/topbar/GlassMediumFlexibleTopAppBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/topbar/GlassMediumFlexibleTopAppBar.kt @@ -16,6 +16,7 @@ import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarColors import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.lerp @@ -187,11 +188,14 @@ object GlassTopAppBarDefaults { val composeEngine = ThemeConfig.composeEngine return if (ThemeResolver.isMiuixEngine(composeEngine)) { - MiuixGlassScrollBehavior(MiuixScrollBehavior()) + val miuixBehavior = MiuixScrollBehavior() + remember(miuixBehavior) { MiuixGlassScrollBehavior(miuixBehavior) } } else if (ThemeConfig.useFlexibleTopAppBar) { - M3GlassScrollBehavior(TopAppBarDefaults.exitUntilCollapsedScrollBehavior()) + val m3Behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() + remember(m3Behavior) { M3GlassScrollBehavior(m3Behavior) } } else { - M3GlassScrollBehavior(TopAppBarDefaults.pinnedScrollBehavior()) + val m3Behavior = TopAppBarDefaults.pinnedScrollBehavior() + remember(m3Behavior) { M3GlassScrollBehavior(m3Behavior) } } }