You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_Patient_App_New/lib/widgets/scroll_wheel_time_picker.dart

182 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ScrollWheelTimePicker extends StatefulWidget {
final int initialHour;
final int initialMinute;
final bool use24HourFormat;
final ValueChanged<TimeOfDay>? onTimeChanged;
final double itemExtent;
final double pickerHeight;
final TextStyle? digitTextStyle;
final TextStyle? separatorTextStyle;
const ScrollWheelTimePicker({
super.key,
this.initialHour = 8,
this.initialMinute = 15,
this.use24HourFormat = true,
this.onTimeChanged,
this.itemExtent = 60,
this.pickerHeight = 180,
this.digitTextStyle,
this.separatorTextStyle,
});
@override
State<ScrollWheelTimePicker> createState() => _ScrollWheelTimePickerState();
}
class _ScrollWheelTimePickerState extends State<ScrollWheelTimePicker> {
late FixedExtentScrollController _hourController;
late FixedExtentScrollController _minuteController;
late int _selectedHour;
late int _selectedMinute;
int get _maxHour => widget.use24HourFormat ? 24 : 12;
@override
void initState() {
super.initState();
_selectedHour = widget.initialHour;
_selectedMinute = widget.initialMinute;
final hourIndex =
widget.use24HourFormat ? _selectedHour : (_selectedHour == 0 ? 11 : _selectedHour - 1);
_hourController = FixedExtentScrollController(initialItem: hourIndex);
_minuteController = FixedExtentScrollController(initialItem: _selectedMinute);
}
@override
void dispose() {
_hourController.dispose();
_minuteController.dispose();
super.dispose();
}
void _notifyChange() {
widget.onTimeChanged?.call(TimeOfDay(hour: _selectedHour, minute: _selectedMinute));
}
TextStyle get _defaultDigitStyle => TextStyle(
fontSize: 72.f,
fontWeight: FontWeight.w800,
color: AppColors.textColor,
letterSpacing: 0,
);
TextStyle get _defaultSeparatorStyle => TextStyle(
fontSize: 40.f,
fontWeight: FontWeight.w800,
color: AppColors.textColor,
letterSpacing: 0,
);
@override
Widget build(BuildContext context) {
final digitStyle = widget.digitTextStyle ?? _defaultDigitStyle;
final separatorStyle = widget.separatorTextStyle ?? _defaultSeparatorStyle;
return SizedBox(
height: widget.pickerHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 150.w,
child: ListWheelScrollView.useDelegate(
controller: _hourController,
itemExtent: widget.itemExtent,
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
onSelectedItemChanged: (index) {
setState(() {
_selectedHour =
widget.use24HourFormat ? index : index + 1;
});
_notifyChange();
},
childDelegate: ListWheelChildBuilderDelegate(
childCount: _maxHour,
builder: (context, index) {
final hour =
widget.use24HourFormat ? index : index + 1;
final isSelected = hour == _selectedHour;
return Visibility(
visible: isSelected,
child: Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 200),
style: digitStyle.copyWith(
color: isSelected
? AppColors.textColor
: AppColors.textColor.withValues(alpha: 0.3),
),
child: Text(hour.toString().padLeft(2, '0')),
),
));
},
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2.w),
child: Text(':', style: separatorStyle),
),
SizedBox(
width: 150.w,
child: ListWheelScrollView.useDelegate(
controller: _minuteController,
itemExtent: widget.itemExtent,
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
onSelectedItemChanged: (index) {
setState(() {
_selectedMinute = index;
});
_notifyChange();
},
childDelegate: ListWheelChildBuilderDelegate(
childCount: 60,
builder: (context, index) {
final isSelected = index == _selectedMinute;
return Visibility(
visible: isSelected,
child:
Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 200),
style: digitStyle.copyWith(
color: isSelected
? AppColors.textColor
: AppColors.transparent.withValues(alpha: 0.3),
),
child: Text(index.toString().padLeft(2, '0')),
),
));
},
),
),
),
],
),
);
}
}