一些优化
This commit is contained in:
@@ -3,6 +3,8 @@ package io.legado.app.ui.widget.components.image.cover
|
|||||||
import androidx.compose.animation.AnimatedVisibilityScope
|
import androidx.compose.animation.AnimatedVisibilityScope
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||||
import androidx.compose.animation.SharedTransitionScope
|
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.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@@ -50,6 +52,18 @@ fun BookshelfCover(
|
|||||||
sharedCoverKey = sharedCoverKey,
|
sharedCoverKey = sharedCoverKey,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 使用 animatedVisibilityScope 的 animateEnterExit 为叠加层添加同步动画
|
||||||
|
val overlayModifier = Modifier.then(
|
||||||
|
if (animatedVisibilityScope != null) {
|
||||||
|
with(animatedVisibilityScope) {
|
||||||
|
Modifier.animateEnterExit(
|
||||||
|
enter = fadeIn(),
|
||||||
|
exit = fadeOut()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else Modifier
|
||||||
|
)
|
||||||
|
|
||||||
if (!badgeText.isNullOrEmpty()) {
|
if (!badgeText.isNullOrEmpty()) {
|
||||||
TextCard(
|
TextCard(
|
||||||
text = badgeText,
|
text = badgeText,
|
||||||
@@ -57,7 +71,8 @@ fun BookshelfCover(
|
|||||||
iconSize = 12.dp,
|
iconSize = 12.dp,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.TopEnd)
|
.align(Alignment.TopEnd)
|
||||||
.padding(2.dp),
|
.padding(2.dp)
|
||||||
|
.then(overlayModifier),
|
||||||
cornerRadius = 4.dp,
|
cornerRadius = 4.dp,
|
||||||
horizontalPadding = 4.dp,
|
horizontalPadding = 4.dp,
|
||||||
verticalPadding = 2.dp
|
verticalPadding = 2.dp
|
||||||
@@ -71,7 +86,8 @@ fun BookshelfCover(
|
|||||||
contentColor = LegadoTheme.colorScheme.onCardContainer,
|
contentColor = LegadoTheme.colorScheme.onCardContainer,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomStart)
|
.align(Alignment.BottomStart)
|
||||||
.padding(2.dp),
|
.padding(2.dp)
|
||||||
|
.then(overlayModifier),
|
||||||
cornerRadius = 4.dp,
|
cornerRadius = 4.dp,
|
||||||
horizontalPadding = 4.dp,
|
horizontalPadding = 4.dp,
|
||||||
verticalPadding = 2.dp
|
verticalPadding = 2.dp
|
||||||
@@ -85,6 +101,7 @@ fun BookshelfCover(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 4.dp, vertical = 6.dp)
|
.padding(horizontal = 4.dp, vertical = 6.dp)
|
||||||
.height(3.dp)
|
.height(3.dp)
|
||||||
|
.then(overlayModifier)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,17 @@ fun CoilBookCover(
|
|||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.aspectRatio(5f / 7f)
|
.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(
|
.then(
|
||||||
if (CoverConfig.coverShowShadow) {
|
if (CoverConfig.coverShowShadow) {
|
||||||
Modifier.shadow(4.dp, RoundedCornerShape(4.dp))
|
Modifier.shadow(4.dp, RoundedCornerShape(4.dp))
|
||||||
@@ -94,67 +105,53 @@ fun CoilBookCover(
|
|||||||
)
|
)
|
||||||
.clip(RoundedCornerShape(4.dp))
|
.clip(RoundedCornerShape(4.dp))
|
||||||
) {
|
) {
|
||||||
val imageContentModifier = Modifier
|
if (hasCustomDefault && !isOnlineCoverLoaded) {
|
||||||
.fillMaxSize()
|
AsyncImage(
|
||||||
.then(
|
model = buildCoverImageRequest(
|
||||||
with(sharedTransitionScope) {
|
context = context,
|
||||||
if (this != null && animatedVisibilityScope != null && sharedCoverKey != null) {
|
data = randomPath,
|
||||||
Modifier.sharedElement(
|
sourceOrigin = null,
|
||||||
sharedContentState = rememberSharedContentState(sharedCoverKey),
|
loadOnlyWifi = false,
|
||||||
animatedVisibilityScope = animatedVisibilityScope,
|
crossfade = showLoadingPlaceholder,
|
||||||
renderInOverlayDuringTransition = true
|
memoryCacheKey = randomPath,
|
||||||
)
|
),
|
||||||
} else Modifier
|
contentDescription = null,
|
||||||
}
|
imageLoader = koinInject(),
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Box(modifier = imageContentModifier) {
|
if (finalPath != null) {
|
||||||
if (hasCustomDefault && !isOnlineCoverLoaded) {
|
AsyncImage(
|
||||||
AsyncImage(
|
model = buildCoverImageRequest(
|
||||||
model = buildCoverImageRequest(
|
context = context,
|
||||||
context = context,
|
data = finalPath,
|
||||||
data = randomPath,
|
sourceOrigin = sourceOrigin,
|
||||||
sourceOrigin = null,
|
loadOnlyWifi = CoverConfig.loadCoverOnlyWifi,
|
||||||
loadOnlyWifi = false,
|
crossfade = showLoadingPlaceholder,
|
||||||
crossfade = showLoadingPlaceholder,
|
memoryCacheKey = finalPath,
|
||||||
),
|
),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
imageLoader = koinInject(),
|
imageLoader = koinInject(),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.clip(RoundedCornerShape(4.dp))
|
.clip(RoundedCornerShape(4.dp)),
|
||||||
)
|
onSuccess = {
|
||||||
}
|
isOnlineCoverLoaded = true
|
||||||
|
onLoadFinish?.invoke()
|
||||||
if (finalPath != null) {
|
},
|
||||||
AsyncImage(
|
onError = {
|
||||||
model = buildCoverImageRequest(
|
isOnlineCoverLoaded = false
|
||||||
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) {
|
|
||||||
onLoadFinish?.invoke()
|
onLoadFinish?.invoke()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
onLoadFinish?.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,18 @@ fun buildCoverImageRequest(
|
|||||||
sourceOrigin: String?,
|
sourceOrigin: String?,
|
||||||
loadOnlyWifi: Boolean,
|
loadOnlyWifi: Boolean,
|
||||||
crossfade: Boolean = true,
|
crossfade: Boolean = true,
|
||||||
|
memoryCacheKey: String? = null,
|
||||||
configure: ImageRequest.Builder.() -> Unit = {},
|
configure: ImageRequest.Builder.() -> Unit = {},
|
||||||
): ImageRequest {
|
): ImageRequest {
|
||||||
return ImageRequest.Builder(context)
|
return ImageRequest.Builder(context)
|
||||||
.data(data)
|
.data(data)
|
||||||
.crossfade(crossfade)
|
.crossfade(crossfade)
|
||||||
|
.apply {
|
||||||
|
if (memoryCacheKey != null) {
|
||||||
|
memoryCacheKey(memoryCacheKey)
|
||||||
|
placeholderMemoryCacheKey(memoryCacheKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
.setParameter("sourceOrigin", sourceOrigin)
|
.setParameter("sourceOrigin", sourceOrigin)
|
||||||
.setParameter("loadOnlyWifi", loadOnlyWifi)
|
.setParameter("loadOnlyWifi", loadOnlyWifi)
|
||||||
.apply(configure)
|
.apply(configure)
|
||||||
|
|||||||
Reference in New Issue
Block a user