增加记录信息修改时间

This commit is contained in:
yovinchen 2024-11-26 22:55:23 +08:00
parent bb619bed78
commit 99a68d3d22
2 changed files with 190 additions and 126 deletions

View File

@ -7,6 +7,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -19,6 +20,7 @@ fun DateTimePicker(
) { ) {
var showDatePicker by remember { mutableStateOf(false) } var showDatePicker by remember { mutableStateOf(false) }
var showTimePicker by remember { mutableStateOf(false) } var showTimePicker by remember { mutableStateOf(false) }
var tempDateTime by remember { mutableStateOf(selectedDateTime) }
val dateFormatter = remember { DateTimeFormatter.ofPattern("yyyy年MM月dd日") } val dateFormatter = remember { DateTimeFormatter.ofPattern("yyyy年MM月dd日") }
val timeFormatter = remember { DateTimeFormatter.ofPattern("HH:mm") } val timeFormatter = remember { DateTimeFormatter.ofPattern("HH:mm") }
@ -55,96 +57,109 @@ fun DateTimePicker(
// 日期选择器对话框 // 日期选择器对话框
if (showDatePicker) { if (showDatePicker) {
val datePickerState = rememberDatePickerState( Dialog(onDismissRequest = { showDatePicker = false }) {
initialSelectedDateMillis = selectedDateTime Surface(
.toLocalDate() modifier = Modifier
.atStartOfDay() .fillMaxWidth()
.toInstant(java.time.ZoneOffset.UTC) .wrapContentHeight(),
.toEpochMilli() shape = MaterialTheme.shapes.extraLarge,
) tonalElevation = 6.dp
) {
DatePickerDialog( Column(
onDismissRequest = { showDatePicker = false }, modifier = Modifier.padding(16.dp)
confirmButton = {
TextButton(
onClick = {
datePickerState.selectedDateMillis?.let { millis ->
val newDate = java.time.Instant.ofEpochMilli(millis)
.atZone(java.time.ZoneOffset.UTC)
.toLocalDate()
val newDateTime = newDate.atTime(
selectedDateTime.hour,
selectedDateTime.minute
)
onDateTimeSelected(newDateTime)
}
showDatePicker = false
}
) { ) {
Text("确定") val datePickerState = rememberDatePickerState(
} initialSelectedDateMillis = selectedDateTime
}, .toLocalDate()
dismissButton = { .atStartOfDay()
TextButton(onClick = { showDatePicker = false }) { .toInstant(java.time.ZoneOffset.UTC)
Text("取消") .toEpochMilli()
)
DatePicker(
state = datePickerState,
showModeToggle = false
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp),
horizontalArrangement = Arrangement.End
) {
TextButton(onClick = { showDatePicker = false }) {
Text("取消")
}
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = {
datePickerState.selectedDateMillis?.let { millis ->
val newDate = java.time.Instant.ofEpochMilli(millis)
.atZone(java.time.ZoneOffset.UTC)
.toLocalDate()
val newDateTime = newDate.atTime(
selectedDateTime.hour,
selectedDateTime.minute
)
onDateTimeSelected(newDateTime)
}
showDatePicker = false
}
) {
Text("确定")
}
}
} }
} }
) {
DatePicker(
state = datePickerState,
showModeToggle = false,
modifier = Modifier.padding(16.dp)
)
} }
} }
// 时间选择器对话框 // 时间选择器对话框
if (showTimePicker) { if (showTimePicker) {
val timePickerState = rememberTimePickerState( Dialog(onDismissRequest = { showTimePicker = false }) {
initialHour = selectedDateTime.hour, Surface(
initialMinute = selectedDateTime.minute modifier = Modifier
) .fillMaxWidth()
.wrapContentHeight(),
TimePickerDialog( shape = MaterialTheme.shapes.extraLarge,
onDismissRequest = { showTimePicker = false }, tonalElevation = 6.dp
confirmButton = { ) {
TextButton( Column(
onClick = { modifier = Modifier.padding(16.dp)
val newDateTime = selectedDateTime
.withHour(timePickerState.hour)
.withMinute(timePickerState.minute)
onDateTimeSelected(newDateTime)
showTimePicker = false
}
) { ) {
Text("确定") val timePickerState = rememberTimePickerState(
} initialHour = selectedDateTime.hour,
}, initialMinute = selectedDateTime.minute
dismissButton = { )
TextButton(onClick = { showTimePicker = false }) {
Text("取消") TimePicker(
state = timePickerState
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp),
horizontalArrangement = Arrangement.End
) {
TextButton(onClick = { showTimePicker = false }) {
Text("取消")
}
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = {
val newDateTime = selectedDateTime
.withHour(timePickerState.hour)
.withMinute(timePickerState.minute)
onDateTimeSelected(newDateTime)
showTimePicker = false
}
) {
Text("确定")
}
}
} }
} }
) {
TimePicker(
state = timePickerState,
modifier = Modifier.padding(16.dp)
)
} }
} }
} }
@Composable
private fun TimePickerDialog(
onDismissRequest: () -> Unit,
confirmButton: @Composable () -> Unit,
dismissButton: @Composable () -> Unit,
content: @Composable () -> Unit
) {
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = confirmButton,
dismissButton = dismissButton,
text = { content() }
)
}

View File

@ -7,8 +7,13 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.yovinchen.bookkeeping.model.BookkeepingRecord import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.Category import com.yovinchen.bookkeeping.model.Category
import com.yovinchen.bookkeeping.ui.components.DateTimePicker
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.Date import java.util.Date
@Composable @Composable
@ -21,17 +26,45 @@ fun RecordEditDialog(
var amount by remember { mutableStateOf(record.amount.toString()) } var amount by remember { mutableStateOf(record.amount.toString()) }
var selectedCategory by remember { mutableStateOf(record.category) } var selectedCategory by remember { mutableStateOf(record.category) }
var description by remember { mutableStateOf(record.description) } var description by remember { mutableStateOf(record.description) }
var expanded by remember { mutableStateOf(false) }
var selectedDateTime by remember {
mutableStateOf(
LocalDateTime.ofInstant(
Instant.ofEpochMilli(record.date.time),
ZoneId.systemDefault()
)
)
}
AlertDialog( Dialog(onDismissRequest = onDismiss) {
onDismissRequest = onDismiss, Card(
title = { Text("编辑记录") }, modifier = Modifier
text = { .fillMaxWidth()
.padding(16.dp),
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(16.dp), .padding(16.dp)
verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
Text(
text = "编辑记录",
style = MaterialTheme.typography.titleLarge
)
Spacer(modifier = Modifier.height(16.dp))
// 日期时间选择
DateTimePicker(
selectedDateTime = selectedDateTime,
onDateTimeSelected = { selectedDateTime = it },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
// 金额输入
OutlinedTextField( OutlinedTextField(
value = amount, value = amount,
onValueChange = { amount = it }, onValueChange = { amount = it },
@ -39,6 +72,41 @@ fun RecordEditDialog(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
Spacer(modifier = Modifier.height(8.dp))
// 类别选择
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = it }
) {
OutlinedTextField(
value = selectedCategory,
onValueChange = {},
readOnly = true,
label = { Text("类别") },
modifier = Modifier
.fillMaxWidth()
.menuAnchor()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
categories.filter { it.type == record.type }.forEach { category ->
DropdownMenuItem(
text = { Text(category.name) },
onClick = {
selectedCategory = category.name
expanded = false
}
)
}
}
}
Spacer(modifier = Modifier.height(8.dp))
// 描述输入
OutlinedTextField( OutlinedTextField(
value = description, value = description,
onValueChange = { description = it }, onValueChange = { description = it },
@ -46,52 +114,33 @@ fun RecordEditDialog(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
ExposedDropdownMenuBox( Spacer(modifier = Modifier.height(16.dp))
expanded = false,
onExpandedChange = {},
) {
OutlinedTextField(
value = selectedCategory,
onValueChange = {},
readOnly = true,
label = { Text("类别") },
modifier = Modifier.fillMaxWidth()
)
DropdownMenu( // 按钮
expanded = false, Row(
onDismissRequest = { }, modifier = Modifier.fillMaxWidth(),
) { horizontalArrangement = Arrangement.End
categories.filter { it.type == record.type }.forEach { category -> ) {
DropdownMenuItem( TextButton(onClick = onDismiss) {
text = { Text(category.name) }, Text("取消")
onClick = { selectedCategory = category.name } }
Spacer(modifier = Modifier.width(8.dp))
Button(
onClick = {
val updatedRecord = record.copy(
amount = amount.toDoubleOrNull() ?: record.amount,
category = selectedCategory,
description = description,
date = Date.from(selectedDateTime.atZone(ZoneId.systemDefault()).toInstant())
) )
onConfirm(updatedRecord)
onDismiss()
} }
) {
Text("确定")
} }
} }
} }
},
confirmButton = {
TextButton(
onClick = {
val updatedRecord = record.copy(
amount = amount.toDoubleOrNull() ?: record.amount,
category = selectedCategory,
description = description,
date = Date()
)
onConfirm(updatedRecord)
onDismiss()
}
) {
Text("确认")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
} }
) }
} }