fix:开了折叠应用栏后下拉刷新的问题 (#1629)

This commit is contained in:
fansan authored and GitHub committed 2026-07-01 23:34:27 +08:00
1 parent 366d547bcd
commit 7ca241e1ae
9 files changed
+51 -20

No files matched your search

@@ -288,7 +288,8 @@ fun ExploreShowScreen(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
isRefreshing = state.isRefreshing, isRefreshing = state.isRefreshing,
onRefresh = { viewModel.onIntent(ExploreShowIntent.Refresh) }, onRefresh = { viewModel.onIntent(ExploreShowIntent.Refresh) },
topPadding = paddingValues.calculateTopPadding() topPadding = paddingValues.calculateTopPadding(),
scrollBehavior = scrollBehavior
) { ) {
Crossfade( Crossfade(
targetState = isGridMode, targetState = isGridMode,
@@ -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.menuItem.RoundDropdownMenuItem
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.text.AppText 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.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.utils.ConvertUtils import io.legado.app.utils.ConvertUtils
import io.legado.app.utils.startActivityForBook import io.legado.app.utils.startActivityForBook
@@ -98,9 +99,11 @@ private fun ImportBookContent(
onDeleteSelection: () -> Unit, onDeleteSelection: () -> Unit,
onItemClick: (ImportBook) -> Unit onItemClick: (ImportBook) -> Unit
) { ) {
val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior()
ListScaffold( ListScaffold(
title = state.pathNames.lastOrNull() ?: stringResource(R.string.local_book), title = state.pathNames.lastOrNull() ?: stringResource(R.string.local_book),
state = state, state = state,
scrollBehavior = scrollBehavior,
onBackClick = onBackClick, onBackClick = onBackClick,
onSearchToggle = onSearchToggle, onSearchToggle = onSearchToggle,
onSearchQueryChange = onSearchQueryChange, onSearchQueryChange = onSearchQueryChange,
@@ -197,7 +200,8 @@ private fun ImportBookContent(
.padding(paddingValues), .padding(paddingValues),
isRefreshing = state.isLoading, isRefreshing = state.isLoading,
onRefresh = onScanFolder, onRefresh = onScanFolder,
topPadding = paddingValues.calculateTopPadding() topPadding = paddingValues.calculateTopPadding(),
scrollBehavior = scrollBehavior
) { ) {
when { when {
state.items.isEmpty() && state.isLoading -> { state.items.isEmpty() && state.isLoading -> {
@@ -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.modalBottomSheet.AppModalBottomSheet
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.text.AppText 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.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.utils.ConvertUtils import io.legado.app.utils.ConvertUtils
import io.legado.app.utils.startActivityForBook import io.legado.app.utils.startActivityForBook
@@ -209,6 +210,8 @@ fun RemoteBookScreen(
} }
} }
val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior()
LaunchedEffect(viewModel) { LaunchedEffect(viewModel) {
viewModel.dispatch(RemoteBookIntent.Initialize) viewModel.dispatch(RemoteBookIntent.Initialize)
viewModel.effects.collect { effect -> viewModel.effects.collect { effect ->
@@ -252,6 +255,7 @@ fun RemoteBookScreen(
ListScaffold( ListScaffold(
title = "远程书籍", title = "远程书籍",
state = uiState, state = uiState,
scrollBehavior = scrollBehavior,
onBackClick = onBackClick, onBackClick = onBackClick,
onSearchToggle = { viewModel.dispatch(RemoteBookIntent.SearchToggle(it)) }, onSearchToggle = { viewModel.dispatch(RemoteBookIntent.SearchToggle(it)) },
onSearchQueryChange = { viewModel.dispatch(RemoteBookIntent.SearchChange(it)) }, onSearchQueryChange = { viewModel.dispatch(RemoteBookIntent.SearchChange(it)) },
@@ -322,7 +326,8 @@ fun RemoteBookScreen(
.padding(paddingValues), .padding(paddingValues),
isRefreshing = uiState.isLoading, isRefreshing = uiState.isLoading,
onRefresh = { viewModel.dispatch(RemoteBookIntent.Refresh) }, onRefresh = { viewModel.dispatch(RemoteBookIntent.Refresh) },
topPadding = paddingValues.calculateTopPadding() topPadding = paddingValues.calculateTopPadding(),
scrollBehavior = scrollBehavior
) { ) {
if (uiState.items.isEmpty()) { if (uiState.items.isEmpty()) {
if (uiState.isLoading) { if (uiState.isLoading) {
@@ -193,7 +193,8 @@ private fun BookInfoScreenContent(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
isRefreshing = state.isTocLoading, isRefreshing = state.isTocLoading,
onRefresh = { onIntent(BookInfoIntent.MenuAction(BookInfoMenuAction.Refresh)) }, onRefresh = { onIntent(BookInfoIntent.MenuAction(BookInfoMenuAction.Refresh)) },
topPadding = paddingValues.calculateTopPadding() topPadding = paddingValues.calculateTopPadding(),
scrollBehavior = scrollBehavior
) { ) {
LazyColumn( LazyColumn(
state = listState, state = listState,
@@ -717,7 +717,8 @@ fun BookshelfScreen(
isRefreshing = uiState.isRefreshing, isRefreshing = uiState.isRefreshing,
onRefresh = { viewModel.refreshBooks(uiState.items) }, onRefresh = { viewModel.refreshBooks(uiState.items) },
enabled = pullToRefreshEnabled, enabled = pullToRefreshEnabled,
topPadding = paddingValues.calculateTopPadding() topPadding = paddingValues.calculateTopPadding(),
scrollBehavior = scrollBehavior
) { ) {
folderTransition.AnimatedContent( folderTransition.AnimatedContent(
transitionSpec = { transitionSpec = {
@@ -452,6 +452,7 @@ fun HomeScreen(
isRefreshing = homepageState.isRefreshing, isRefreshing = homepageState.isRefreshing,
onRefresh = onRefreshHomepage, onRefresh = onRefreshHomepage,
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
scrollBehavior = scrollBehavior,
) { ) {
BoxWithConstraints(modifier = Modifier.fillMaxSize()) { BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
val dashboardScrollState = rememberScrollState() val dashboardScrollState = rememberScrollState()
@@ -21,6 +21,9 @@ import androidx.compose.ui.unit.dp
import io.legado.app.R import io.legado.app.R
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver 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 kotlinx.coroutines.delay
import top.yukonga.miuix.kmp.basic.PullToRefresh as MiuixPullToRefresh import top.yukonga.miuix.kmp.basic.PullToRefresh as MiuixPullToRefresh
import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState as miuixRememberPullToRefreshState import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState as miuixRememberPullToRefreshState
@@ -33,6 +36,7 @@ fun AppPullToRefresh(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true, enabled: Boolean = true,
topPadding: Dp = 0.dp, topPadding: Dp = 0.dp,
scrollBehavior: GlassTopAppBarScrollBehavior? = null,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
if (ThemeResolver.isMiuixEngine(composeEngine)) { if (ThemeResolver.isMiuixEngine(composeEngine)) {
@@ -58,6 +62,7 @@ fun AppPullToRefresh(
modifier = modifier, modifier = modifier,
contentPadding = PaddingValues(top = topPadding + 16.dp), contentPadding = PaddingValues(top = topPadding + 16.dp),
pullToRefreshState = miuixRememberPullToRefreshState(), pullToRefreshState = miuixRememberPullToRefreshState(),
topAppBarScrollBehavior = (scrollBehavior as? MiuixGlassScrollBehavior)?.miuixBehavior,
refreshTexts = listOf( refreshTexts = listOf(
stringResource(R.string.pull_to_refresh), stringResource(R.string.pull_to_refresh),
stringResource(R.string.release_to_refresh), stringResource(R.string.release_to_refresh),
@@ -69,22 +74,31 @@ fun AppPullToRefresh(
} }
} else { } else {
val state = rememberPullToRefreshState() 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( PullToRefreshBox(
isRefreshing = isRefreshing, isRefreshing = isRefreshing,
onRefresh = onRefresh, onRefresh = onRefresh,
modifier = modifier, modifier = modifier,
state = state, state = state,
enabled = enabled, enabled = actualEnabled,
indicator = { indicator = {
if (enabled) { PullToRefreshDefaults.LoadingIndicator(
PullToRefreshDefaults.LoadingIndicator( state = state,
state = state, isRefreshing = isRefreshing,
isRefreshing = isRefreshing, modifier = Modifier
modifier = Modifier .padding(top = topPadding)
.padding(top = topPadding) .align(Alignment.TopCenter),
.align(Alignment.TopCenter), )
)
}
} }
) { ) {
content() content()
@@ -75,10 +75,10 @@ fun <T> ListScaffold(
}, },
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }, snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
scrollBehavior: GlassTopAppBarScrollBehavior? = null,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior() val scrollBehavior = scrollBehavior ?: GlassTopAppBarDefaults.defaultScrollBehavior()
AppScaffold( AppScaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
snackbarHost = { snackbarHost = {
@@ -16,6 +16,7 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarColors import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp import androidx.compose.ui.graphics.lerp
@@ -187,11 +188,14 @@ object GlassTopAppBarDefaults {
val composeEngine = ThemeConfig.composeEngine val composeEngine = ThemeConfig.composeEngine
return if (ThemeResolver.isMiuixEngine(composeEngine)) { return if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixGlassScrollBehavior(MiuixScrollBehavior()) val miuixBehavior = MiuixScrollBehavior()
remember(miuixBehavior) { MiuixGlassScrollBehavior(miuixBehavior) }
} else if (ThemeConfig.useFlexibleTopAppBar) { } else if (ThemeConfig.useFlexibleTopAppBar) {
M3GlassScrollBehavior(TopAppBarDefaults.exitUntilCollapsedScrollBehavior()) val m3Behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
remember(m3Behavior) { M3GlassScrollBehavior(m3Behavior) }
} else { } else {
M3GlassScrollBehavior(TopAppBarDefaults.pinnedScrollBehavior()) val m3Behavior = TopAppBarDefaults.pinnedScrollBehavior()
remember(m3Behavior) { M3GlassScrollBehavior(m3Behavior) }
} }
} }