一些优化

This commit is contained in:
HapeLee
2026-05-17 21:03:25 +08:00
parent f4ca57f972
commit 3215adde42
3 changed files with 80 additions and 59 deletions
@@ -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)
)
}
}
@@ -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()
}
}
@@ -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)