mirror of https://github.com/Ashinch/ReadYou.git
98 lines
3.1 KiB
Kotlin
98 lines
3.1 KiB
Kotlin
package me.ash.reader.ui.widget
|
|
|
|
import androidx.compose.animation.ExperimentalAnimationApi
|
|
import androidx.compose.animation.core.*
|
|
import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.lazy.LazyListState
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.geometry.Offset
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.unit.sp
|
|
import androidx.compose.ui.zIndex
|
|
import me.ash.reader.ui.util.calculateTopBarAnimateValue
|
|
|
|
@ExperimentalAnimationApi
|
|
@Composable
|
|
fun BoxScope.TopTitleBox(
|
|
title: String,
|
|
description: String,
|
|
listState: LazyListState,
|
|
SpacerHeight: Float = Float.NaN,
|
|
startOffset: Offset,
|
|
startHeight: Float,
|
|
startTitleFontSize: Float,
|
|
startDescriptionFontSize: Float,
|
|
clickable: () -> Unit = {},
|
|
) {
|
|
val transition = updateTransition(targetState = listState, label = "")
|
|
val offset by transition.animateOffset(
|
|
label = "",
|
|
transitionSpec = { spring() }
|
|
) {
|
|
Offset(
|
|
x = it.calculateTopBarAnimateValue(startOffset.x, 56f),
|
|
y = it.calculateTopBarAnimateValue(startOffset.y, 0f)
|
|
)
|
|
}
|
|
|
|
val height by transition.animateFloat(
|
|
label = "",
|
|
transitionSpec = { spring() }
|
|
) {
|
|
it.calculateTopBarAnimateValue(startHeight, 64f)
|
|
}
|
|
|
|
val titleFontSize by transition.animateFloat(
|
|
label = "",
|
|
transitionSpec = { spring(stiffness = Spring.StiffnessHigh) }
|
|
) {
|
|
it.calculateTopBarAnimateValue(startTitleFontSize, 16f)
|
|
}
|
|
|
|
val descriptionFontSize by transition.animateFloat(
|
|
label = "",
|
|
transitionSpec = { spring(stiffness = Spring.StiffnessHigh) }
|
|
) {
|
|
it.calculateTopBarAnimateValue(startDescriptionFontSize, 12f)
|
|
}
|
|
|
|
Box(
|
|
modifier = Modifier
|
|
.zIndex(1f)
|
|
.height(height.dp)
|
|
.offset(offset.x.dp, offset.y.dp)
|
|
.clickable(
|
|
interactionSource = MutableInteractionSource(),
|
|
indication = null,
|
|
onClickLabel = "回到顶部",
|
|
onClick = clickable ?: {}
|
|
),
|
|
contentAlignment = Alignment.Center
|
|
) {
|
|
Column {
|
|
AnimatedText(
|
|
text = title,
|
|
fontWeight = FontWeight.Bold,
|
|
fontSize = titleFontSize.sp,
|
|
color = MaterialTheme.colorScheme.primary
|
|
)
|
|
Spacer(modifier = Modifier.height(SpacerHeight.dp))
|
|
AnimatedText(
|
|
text = description,
|
|
fontWeight = FontWeight.SemiBold,
|
|
fontSize = descriptionFontSize.sp,
|
|
color = MaterialTheme.colorScheme.secondary,
|
|
maxLines = 1,
|
|
overflow = TextOverflow.Ellipsis,
|
|
)
|
|
}
|
|
}
|
|
} |