fix:日历选择交互

This commit is contained in:
jingyun
2026-06-23 10:18:36 +08:00
parent 8cf919283b
commit d59c3212b8
2 changed files with 72 additions and 3 deletions
@@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart' hide AssetImage; import 'package:flutter/material.dart' hide AssetImage;
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@@ -109,19 +110,40 @@ class _AssetAddPageState extends ConsumerState<AssetAddPage> {
} }
Future<void> pickDate(BuildContext context) async { Future<void> pickDate(BuildContext context) async {
final today = DateTime.now();
final parsed = _parseDate(_dateCtrl.text.trim());
final initialDate = parsed == null
? today
: parsed.isBefore(DateTime(2000))
? DateTime(2000)
: parsed.isAfter(today)
? today
: parsed;
final DateTime? picked = await showDatePicker( final DateTime? picked = await showDatePicker(
context: context, context: context,
initialDate: DateTime.now(), initialDate: initialDate,
firstDate: DateTime(2000), firstDate: DateTime(2000),
lastDate: DateTime.now(), lastDate: today,
initialEntryMode: DatePickerEntryMode.calendarOnly,
locale: const Locale('zh'), locale: const Locale('zh'),
); );
if (picked != null) { if (picked != null) {
print(picked.toString()); setState(() {
_dateCtrl.text = _formatDate(picked);
});
} }
} }
String _formatDate(DateTime value) {
return '${value.year}-${value.month.toString().padLeft(2, '0')}-${value.day.toString().padLeft(2, '0')}';
}
DateTime? _parseDate(String value) {
if (value.isEmpty) return null;
return DateTime.tryParse(value);
}
Future<void> _showImageSourceSheet() async { Future<void> _showImageSourceSheet() async {
if (!mounted) return; if (!mounted) return;
showModalBottomSheet<void>( showModalBottomSheet<void>(
@@ -702,6 +724,11 @@ class _AssetAddPageState extends ConsumerState<AssetAddPage> {
keyboardType: const TextInputType.numberWithOptions( keyboardType: const TextInputType.numberWithOptions(
decimal: true, decimal: true,
), ),
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9.]'),
),
],
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
isDense: true, isDense: true,
@@ -715,9 +742,12 @@ class _AssetAddPageState extends ConsumerState<AssetAddPage> {
label: '购买日期', label: '购买日期',
child: TextField( child: TextField(
controller: _dateCtrl, controller: _dateCtrl,
readOnly: true,
onTap: () => pickDate(context),
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
isDense: true, isDense: true,
hintText: 'YYYY-MM-DD',
), ),
textAlign: TextAlign.right, textAlign: TextAlign.right,
), ),
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:shadcn_ui/shadcn_ui.dart';
@@ -50,6 +51,39 @@ class _AssetEditPageState extends ConsumerState<AssetEditPage> {
_channelCtrl = TextEditingController(text: _holding.channel ?? ''); _channelCtrl = TextEditingController(text: _holding.channel ?? '');
} }
Future<void> pickDate(BuildContext context) async {
final today = DateTime.now();
final parsed = _parseDate(_dateCtrl.text.trim()) ?? _holding.purchaseDate;
final initialDate = parsed == null
? today
: parsed.isBefore(DateTime(2000))
? DateTime(2000)
: parsed.isAfter(today)
? today
: parsed;
final picked = await showDatePicker(
context: context,
initialDate: initialDate,
firstDate: DateTime(2000),
lastDate: today,
initialEntryMode: DatePickerEntryMode.calendarOnly,
locale: const Locale('zh'),
);
if (picked == null || !mounted) return;
setState(() {
_dateCtrl.text = _formatDate(picked);
});
}
String _formatDate(DateTime value) {
return '${value.year}-${value.month.toString().padLeft(2, '0')}-${value.day.toString().padLeft(2, '0')}';
}
DateTime? _parseDate(String value) {
if (value.isEmpty) return null;
return DateTime.tryParse(value);
}
@override @override
void dispose() { void dispose() {
_weightCtrl.dispose(); _weightCtrl.dispose();
@@ -214,6 +248,9 @@ class _AssetEditPageState extends ConsumerState<AssetEditPage> {
keyboardType: const TextInputType.numberWithOptions( keyboardType: const TextInputType.numberWithOptions(
decimal: true, decimal: true,
), ),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')),
],
textAlign: TextAlign.right, textAlign: TextAlign.right,
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
@@ -227,6 +264,8 @@ class _AssetEditPageState extends ConsumerState<AssetEditPage> {
label: '购买日期', label: '购买日期',
child: TextField( child: TextField(
controller: _dateCtrl, controller: _dateCtrl,
readOnly: true,
onTap: () => pickDate(context),
textAlign: TextAlign.right, textAlign: TextAlign.right,
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,