实现缩放动画菜单和 Scrim 关闭

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-18 11:49:45 +08:00
parent ff3bd6629d
commit 37af18ad8d

View File

@ -5,6 +5,7 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut import androidx.compose.animation.scaleOut
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -18,6 +19,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
@ -368,7 +371,11 @@ fun CalendarMonthView(
} }
// Scrim菜单展开时覆盖全屏点击关闭 // Scrim菜单展开时覆盖全屏点击关闭
if (isMenuExpanded) { AnimatedVisibility(
visible = isMenuExpanded,
enter = fadeIn(tween(300)),
exit = fadeOut(tween(200))
) {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -383,43 +390,45 @@ fun CalendarMonthView(
AnimatedVisibility( AnimatedVisibility(
visible = isMenuExpanded, visible = isMenuExpanded,
enter = scaleIn( enter = scaleIn(
initialScale = 0.6f, initialScale = 0.2f,
animationSpec = tween(150), animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing),
transformOrigin = TransformOrigin(0f, 1f) transformOrigin = TransformOrigin(0f, 1f)
) + fadeIn(tween(150)), ) + fadeIn(tween(300)),
exit = scaleOut( exit = scaleOut(
targetScale = 0.6f, targetScale = 0.2f,
animationSpec = tween(100), animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing),
transformOrigin = TransformOrigin(0f, 1f) transformOrigin = TransformOrigin(0f, 1f)
) + fadeOut(tween(100)), ) + fadeOut(tween(200)),
modifier = Modifier modifier = Modifier
.align(Alignment.BottomStart) .align(Alignment.BottomStart)
.padding(start = 16.dp, bottom = with(density) { cardHeightPx.toDp() } + 72.dp) .padding(
start = 16.dp,
bottom = with(density) { cardHeightPx.toDp() } + 16.dp + 56.dp + 8.dp
)
) { ) {
Column( Card(
modifier = Modifier shape = RoundedCornerShape(12.dp),
.background( elevation = CardDefaults.cardElevation(defaultElevation = 3.dp),
MaterialTheme.colorScheme.surfaceContainerHigh, colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerHigh)
RoundedCornerShape(12.dp)
)
.width(140.dp)
) { ) {
MenuItem( Column(modifier = Modifier.width(140.dp)) {
text = "月视图", MenuItem(
selected = !viewModel.isYearView, text = "月视图",
onClick = { selected = !viewModel.isYearView,
isMenuExpanded = false onClick = {
if (viewModel.isYearView) viewModel.toggleYearView() isMenuExpanded = false
} if (viewModel.isYearView) viewModel.toggleYearView()
) }
MenuItem( )
text = "年视图", MenuItem(
selected = viewModel.isYearView, text = "年视图",
onClick = { selected = viewModel.isYearView,
isMenuExpanded = false onClick = {
if (!viewModel.isYearView) viewModel.toggleYearView() isMenuExpanded = false
} if (!viewModel.isYearView) viewModel.toggleYearView()
) }
)
}
} }
} }
} }
@ -436,8 +445,11 @@ private fun MenuItem(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(onClick = onClick) .clickable(onClick = onClick)
.background( .then(
if (selected) MaterialTheme.colorScheme.primaryContainer else Color.Transparent if (selected) Modifier.background(
MaterialTheme.colorScheme.primaryContainer,
RoundedCornerShape(8.dp)
) else Modifier
) )
.padding(horizontal = 16.dp, vertical = 12.dp) .padding(horizontal = 16.dp, vertical = 12.dp)
) { ) {