增加记录信息修改时间
This commit is contained in:
parent
bb619bed78
commit
99a68d3d22
@ -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() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -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("取消")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user