| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import 'package:flutter/material.dart';
- import 'package:intl/intl.dart';
- /// 通用日期选择器组件
- /// 支持功能:
- /// - 初始日期设置
- /// - 日期范围限制
- /// - 自定义日期格式
- /// - 主题适配
- /// - 空值处理
- /// - 验证支持
- class DatePickerField extends StatefulWidget {
- final DateTime? initialDate;
- final DateTime? firstDate;
- final DateTime? lastDate;
- final ValueChanged<DateTime?> onDateSelected;
- final String labelText;
- final String? hintText;
- final bool isRequired;
- final TextStyle? textStyle;
- final InputDecoration? decoration;
- final DateFormat? dateFormat;
- final bool allowClear;
- final bool autoValidate;
- const DatePickerField({
- super.key,
- this.initialDate,
- this.firstDate,
- this.lastDate,
- required this.onDateSelected,
- this.labelText = '选择日期',
- this.hintText,
- this.isRequired = false,
- this.textStyle,
- this.decoration,
- this.dateFormat,
- this.allowClear = true,
- this.autoValidate = false,
- });
- @override
- State<DatePickerField> createState() => _DatePickerFieldState();
- }
- class _DatePickerFieldState extends State<DatePickerField> {
- late final TextEditingController _controller;
- DateTime? _selectedDate;
- final DateFormat _defaultFormat = DateFormat('yyyy-MM-dd');
- @override
- void initState() {
- super.initState();
- _selectedDate = widget.initialDate;
- _controller = TextEditingController(
- text: _selectedDate != null ? _getFormattedDate(_selectedDate!) : '',
- );
- }
- @override
- void didUpdateWidget(covariant DatePickerField oldWidget) {
- if (widget.initialDate != oldWidget.initialDate) {
- _updateDate(widget.initialDate);
- }
- super.didUpdateWidget(oldWidget);
- }
- String _getFormattedDate(DateTime date) {
- return (widget.dateFormat ?? _defaultFormat).format(date);
- }
- void _updateDate(DateTime? newDate) {
- setState(() {
- _selectedDate = newDate;
- _controller.text = newDate != null ? _getFormattedDate(newDate) : '';
- });
- widget.onDateSelected(newDate);
- }
- Future<void> _selectDate() async {
- final DateTime? picked = await showDatePicker(
- context: context,
- initialDate: _selectedDate ?? DateTime.now(),
- firstDate: widget.firstDate ?? DateTime(1900),
- lastDate: widget.lastDate ?? DateTime(2100),
- builder: (context, child) {
- return Theme(
- data: Theme.of(context).copyWith(
- colorScheme: ColorScheme.light(
- primary: Theme.of(context).primaryColor,
- ),
- ),
- child: child!,
- );
- },
- );
- if (picked != null && picked != _selectedDate) {
- _updateDate(picked);
- }
- }
- void _clearDate() {
- _updateDate(null);
- }
- String? _validateDate(String? value) {
- if (widget.isRequired && _selectedDate == null) {
- return '请选择日期';
- }
- return null;
- }
- @override
- Widget build(BuildContext context) {
- return TextFormField(
- controller: _controller,
- readOnly: true,
- style: widget.textStyle ?? Theme.of(context).textTheme.bodyMedium,
- decoration: (widget.decoration ?? InputDecoration(
- labelText: widget.labelText,
- hintText: widget.hintText,
- suffixIcon: _buildSuffixIcon(),
- )).copyWith(
- errorStyle: const TextStyle(height: 0.7),
- ),
- onTap: _selectDate,
- validator: widget.autoValidate ? _validateDate : null,
- );
- }
- Widget _buildSuffixIcon() {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- if (widget.allowClear && _selectedDate != null)
- IconButton(
- icon: const Icon(Icons.clear, size: 18),
- onPressed: _clearDate,
- ),
- const Padding(
- padding: EdgeInsets.only(right: 8),
- child: Icon(Icons.calendar_today, size: 18),
- ),
- ],
- );
- }
- @override
- void dispose() {
- _controller.dispose();
- super.dispose();
- }
- }
|