From 3215adde427d6956d47bd41f2b9ddf01a2356e03 Mon Sep 17 00:00:00 2001 From: HapeLee <63206378+HapeLee@users.noreply.github.com> Date: Sun, 17 May 2026 21:03:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/image/cover/BookshelfCover.kt | 21 +++- .../components/image/cover/CoilBookCover.kt | 111 +++++++++--------- .../image/cover/CoverImageRequest.kt | 7 ++ 3 files changed, 80 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/BookshelfCover.kt b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/BookshelfCover.kt index c358942e3..9ea0265d6 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/BookshelfCover.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/BookshelfCover.kt @@ -3,6 +3,8 @@ package io.legado.app.ui.widget.components.image.cover import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionScope +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -50,6 +52,18 @@ fun BookshelfCover( sharedCoverKey = sharedCoverKey, ) + // 使用 animatedVisibilityScope 的 animateEnterExit 为叠加层添加同步动画 + val overlayModifier = Modifier.then( + if (animatedVisibilityScope != null) { + with(animatedVisibilityScope) { + Modifier.animateEnterExit( + enter = fadeIn(), + exit = fadeOut() + ) + } + } else Modifier + ) + if (!badgeText.isNullOrEmpty()) { TextCard( text = badgeText, @@ -57,7 +71,8 @@ fun BookshelfCover( iconSize = 12.dp, modifier = Modifier .align(Alignment.TopEnd) - .padding(2.dp), + .padding(2.dp) + .then(overlayModifier), cornerRadius = 4.dp, horizontalPadding = 4.dp, verticalPadding = 2.dp @@ -71,7 +86,8 @@ fun BookshelfCover( contentColor = LegadoTheme.colorScheme.onCardContainer, modifier = Modifier .align(Alignment.BottomStart) - .padding(2.dp), + .padding(2.dp) + .then(overlayModifier), cornerRadius = 4.dp, horizontalPadding = 4.dp, verticalPadding = 2.dp @@ -85,6 +101,7 @@ fun BookshelfCover( .fillMaxWidth() .padding(horizontal = 4.dp, vertical = 6.dp) .height(3.dp) + .then(overlayModifier) ) } } diff --git a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoilBookCover.kt b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoilBookCover.kt index e65aa82c2..eea7a5477 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoilBookCover.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoilBookCover.kt @@ -81,6 +81,17 @@ fun CoilBookCover( Box( modifier = modifier .aspectRatio(5f / 7f) + .then( + with(sharedTransitionScope) { + if (this != null && animatedVisibilityScope != null && sharedCoverKey != null) { + Modifier.sharedElement( + sharedContentState = rememberSharedContentState(sharedCoverKey), + animatedVisibilityScope = animatedVisibilityScope, + renderInOverlayDuringTransition = true + ) + } else Modifier + } + ) .then( if (CoverConfig.coverShowShadow) { Modifier.shadow(4.dp, RoundedCornerShape(4.dp)) @@ -94,67 +105,53 @@ fun CoilBookCover( ) .clip(RoundedCornerShape(4.dp)) ) { - val imageContentModifier = Modifier - .fillMaxSize() - .then( - with(sharedTransitionScope) { - if (this != null && animatedVisibilityScope != null && sharedCoverKey != null) { - Modifier.sharedElement( - sharedContentState = rememberSharedContentState(sharedCoverKey), - animatedVisibilityScope = animatedVisibilityScope, - renderInOverlayDuringTransition = true - ) - } else Modifier - } + if (hasCustomDefault && !isOnlineCoverLoaded) { + AsyncImage( + model = buildCoverImageRequest( + context = context, + data = randomPath, + sourceOrigin = null, + loadOnlyWifi = false, + crossfade = showLoadingPlaceholder, + memoryCacheKey = randomPath, + ), + contentDescription = null, + imageLoader = koinInject(), + contentScale = ContentScale.Crop, + modifier = Modifier + .fillMaxSize() + .clip(RoundedCornerShape(4.dp)) ) + } - Box(modifier = imageContentModifier) { - if (hasCustomDefault && !isOnlineCoverLoaded) { - AsyncImage( - model = buildCoverImageRequest( - context = context, - data = randomPath, - sourceOrigin = null, - loadOnlyWifi = false, - crossfade = showLoadingPlaceholder, - ), - contentDescription = null, - imageLoader = koinInject(), - contentScale = ContentScale.Crop, - modifier = Modifier - .fillMaxSize() - .clip(RoundedCornerShape(4.dp)) - ) - } - - if (finalPath != null) { - AsyncImage( - model = buildCoverImageRequest( - context = context, - data = finalPath, - sourceOrigin = sourceOrigin, - loadOnlyWifi = CoverConfig.loadCoverOnlyWifi, - crossfade = showLoadingPlaceholder, - ), - contentDescription = null, - imageLoader = koinInject(), - contentScale = ContentScale.Crop, - modifier = Modifier - .fillMaxSize() - .clip(RoundedCornerShape(4.dp)), - onSuccess = { - isOnlineCoverLoaded = true - onLoadFinish?.invoke() - }, - onError = { - isOnlineCoverLoaded = false - onLoadFinish?.invoke() - } - ) - } else { - LaunchedEffect(Unit) { + if (finalPath != null) { + AsyncImage( + model = buildCoverImageRequest( + context = context, + data = finalPath, + sourceOrigin = sourceOrigin, + loadOnlyWifi = CoverConfig.loadCoverOnlyWifi, + crossfade = showLoadingPlaceholder, + memoryCacheKey = finalPath, + ), + contentDescription = null, + imageLoader = koinInject(), + contentScale = ContentScale.Crop, + modifier = Modifier + .fillMaxSize() + .clip(RoundedCornerShape(4.dp)), + onSuccess = { + isOnlineCoverLoaded = true + onLoadFinish?.invoke() + }, + onError = { + isOnlineCoverLoaded = false onLoadFinish?.invoke() } + ) + } else { + LaunchedEffect(Unit) { + onLoadFinish?.invoke() } } diff --git a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoverImageRequest.kt b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoverImageRequest.kt index 318d3f3b9..10c06ed30 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoverImageRequest.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/image/cover/CoverImageRequest.kt @@ -9,11 +9,18 @@ fun buildCoverImageRequest( sourceOrigin: String?, loadOnlyWifi: Boolean, crossfade: Boolean = true, + memoryCacheKey: String? = null, configure: ImageRequest.Builder.() -> Unit = {}, ): ImageRequest { return ImageRequest.Builder(context) .data(data) .crossfade(crossfade) + .apply { + if (memoryCacheKey != null) { + memoryCacheKey(memoryCacheKey) + placeholderMemoryCacheKey(memoryCacheKey) + } + } .setParameter("sourceOrigin", sourceOrigin) .setParameter("loadOnlyWifi", loadOnlyWifi) .apply(configure)