From 24cb8fd3fe0bc68401cd8539d024301f00cda917 Mon Sep 17 00:00:00 2001 From: xfy Date: Mon, 1 Jun 2026 16:41:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=A3=80=E6=9F=A5=E5=99=A8=E6=96=B0=E8=A1=8C=E5=85=A5?= =?UTF-8?q?=E5=9C=BA=E5=8A=A8=E7=94=BB=E4=B8=8E=E9=AB=98=E4=BA=AE=E5=8A=A8?= =?UTF-8?q?=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 ExpiryRow.isNew 字段及相关入场淡入+上滑动效 - 移除 highlightedRowId 高亮逻辑及相关动画 - simplify animateItem() 为默认参数 - 用 Spacer 替代 verticalArrangement 实现行间距 - 用 animateScrollToItem 替代 scrollToItem + delay 模式 --- .../plus/rua/project/ui/DateCheckerScreen.kt | 78 ++++--------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/core/src/main/kotlin/plus/rua/project/ui/DateCheckerScreen.kt b/core/src/main/kotlin/plus/rua/project/ui/DateCheckerScreen.kt index 4f981fd..e974dea 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/DateCheckerScreen.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/DateCheckerScreen.kt @@ -43,18 +43,15 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset -import androidx.compose.animation.core.animateFloatAsState import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId @@ -63,6 +60,7 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import kotlin.time.Clock +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.datetime.DatePeriod import kotlin.time.Instant @@ -74,7 +72,7 @@ import kotlinx.datetime.plus import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.todayIn -private data class ExpiryRow(val id: Int, val days: Int? = null, val isNew: Boolean = false) +private data class ExpiryRow(val id: Int, val days: Int? = null) private sealed class DatePickerTarget { data object Production : DatePickerTarget() @@ -130,7 +128,6 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { var showDatePicker by remember { mutableStateOf(false) } var datePickerTarget by remember { mutableStateOf(null) } - var highlightedRowId by remember { mutableIntStateOf(-1) } val listState = rememberLazyListState() val scope = rememberCoroutineScope() @@ -161,13 +158,11 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { FloatingActionButton( onClick = { val newId = nextId - rows = rows + ExpiryRow(newId, null, isNew = true) + rows = rows + ExpiryRow(newId, null) nextId++ - highlightedRowId = newId scope.launch { - listState.scrollToItem(rows.size) - kotlinx.coroutines.delay(800) - highlightedRowId = -1 + delay(50) + listState.animateScrollToItem(rows.size - 1) } }, modifier = Modifier.testTag("date_checker_fab"), @@ -221,8 +216,9 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { LazyColumn( state = listState, - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier + .fillMaxWidth() + .weight(1f), contentPadding = PaddingValues(horizontal = 16.dp, vertical = 4.dp) ) { items(rows, key = { it.id }) { row -> @@ -250,12 +246,7 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { SwipeToDismissBox( state = dismissState, - modifier = Modifier.animateItem( - placementSpec = androidx.compose.animation.core.tween( - durationMillis = 400, - easing = androidx.compose.animation.core.FastOutSlowInEasing - ) - ), + modifier = Modifier.animateItem(), backgroundContent = { Box( modifier = Modifier @@ -278,8 +269,6 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { expiryDate = expiryDate, daysRemaining = daysRemaining, status = status, - isHighlighted = row.id == highlightedRowId, - isNew = row.isNew, onDaysChange = { newDays -> rows = rows.map { if (it.id == row.id) it.copy(days = newDays) else it @@ -294,14 +283,13 @@ fun DateCheckerScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { onShowDatePicker = { datePickerTarget = DatePickerTarget.Row(row.id) showDatePicker = true - }, - onNewRowAnimated = { - rows = rows.map { - if (it.id == row.id) it.copy(isNew = false) else it - } } ) } + + if (row.id != rows.lastOrNull()?.id) { + Spacer(modifier = Modifier.height(10.dp)) + } } } } @@ -435,57 +423,19 @@ private fun ExpiryCard( expiryDate: LocalDate?, daysRemaining: Int?, status: ExpiryStatus, - isHighlighted: Boolean, - isNew: Boolean, onDaysChange: (Int?) -> Unit, onExpiryDateChange: (LocalDate) -> Unit, onShowDatePicker: () -> Unit, - onNewRowAnimated: () -> Unit, modifier: Modifier = Modifier ) { var daysText by remember(days) { mutableStateOf(days?.toString() ?: "") } var dateText by remember(expiryDate) { mutableStateOf(expiryDate?.toString() ?: "") } - val density = androidx.compose.ui.platform.LocalDensity.current - val enterOffsetPx = remember(density) { with(density) { 20.dp.toPx() } } - - val animatedAlpha by animateFloatAsState( - targetValue = if (isNew) 0f else 1f, - animationSpec = androidx.compose.animation.core.tween(350, delayMillis = 50), - label = "enterAlpha" - ) - val animatedOffset by animateFloatAsState( - targetValue = if (isNew) enterOffsetPx else 0f, - animationSpec = androidx.compose.animation.core.tween(350, delayMillis = 50), - label = "enterOffset" - ) - - LaunchedEffect(Unit) { - if (isNew) { - kotlinx.coroutines.delay(50) - onNewRowAnimated() - } - } - - val backgroundColor by androidx.compose.animation.animateColorAsState( - targetValue = if (isHighlighted) { - MaterialTheme.colorScheme.primaryContainer - } else { - MaterialTheme.colorScheme.surfaceContainerHigh - }, - animationSpec = androidx.compose.animation.core.tween(400), - label = "highlight" - ) - Box( modifier = modifier .fillMaxWidth() .clip(RoundedCornerShape(16.dp)) - .background(backgroundColor) - .graphicsLayer( - alpha = animatedAlpha, - translationY = animatedOffset - ) + .background(MaterialTheme.colorScheme.surfaceContainerHigh) ) { Column( modifier = Modifier