import 'package:flutter/material.dart'; class DurationPicker extends StatefulWidget { const DurationPicker({ super.key, required this.onChangedCallback, required this.width, required this.height, }); final void Function(Duration duration) onChangedCallback; final double width; final double height; @override State createState() => _DurationPickerState(); } class _DurationPickerState extends State { String _timeString = ''; @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: widget.width, height: widget.height / 4, child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( _timeString.padLeft(4, '0').substring(0, 2), style: Theme.of(context).textTheme.displayMedium, ), Padding(padding: EdgeInsets.only(left: 5)), Text( 'h', style: Theme.of(context).textTheme.bodyLarge!.copyWith(height: 2), ), Padding(padding: EdgeInsets.only(left: 10)), Text( _timeString.padLeft(4, '0').substring(2, 4), style: Theme.of(context).textTheme.displayMedium, ), Padding(padding: EdgeInsets.only(left: 5)), Text( 'm', style: Theme.of(context).textTheme.bodyLarge!.copyWith(height: 2), ), ], ), ), Padding(padding: EdgeInsets.only(top: 10)), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(7), child: _getTextWidget('7'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(8), child: _getTextWidget('8'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(9), child: _getTextWidget('9'), ), ), ), ], ), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(4), child: _getTextWidget('4'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(5), child: _getTextWidget('5'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(6), child: _getTextWidget('6'), ), ), ), ], ), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(1), child: _getTextWidget('1'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(2), child: _getTextWidget('2'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(3), child: _getTextWidget('3'), ), ), ), ], ), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding(padding: EdgeInsets.all(0)), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: () => _addTime(0), child: _getTextWidget('0'), ), ), ), SizedBox( width: widget.width / 3, height: widget.height / 4, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), child: ElevatedButton( style: _buttonTheme, onPressed: _removeTime, child: Icon( Icons.backspace, size: 24, ), ), ), ), ], ), // Expanded( // child: GridView.count( // crossAxisSpacing: 10, // mainAxisSpacing: 10, // crossAxisCount: 3, // shrinkWrap: true, // physics: NeverScrollableScrollPhysics(), // children: [ // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(7), // child: _getTextWidget('7'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(8), // child: _getTextWidget('8'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(9), // child: _getTextWidget('9'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(4), // child: _getTextWidget('4'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(5), // child: _getTextWidget('5'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(6), // child: _getTextWidget('6'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(1), // child: _getTextWidget('1'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(2), // child: _getTextWidget('2'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(3), // child: _getTextWidget('3'), // ), // Padding(padding: EdgeInsets.all(0)), // ElevatedButton( // style: _buttonTheme, // onPressed: () => _addTime(0), // child: _getTextWidget('0'), // ), // ElevatedButton( // style: _buttonTheme, // onPressed: _removeTime, // child: Icon( // Icons.backspace, // size: 24, // ), // ), // ], // ), // ), ], ); } Text _getTextWidget(String text) { return Text(text); } void _addTime(int time) { if (_timeString.length >= 4) return; setState(() { _timeString += time.toString(); }); widget.onChangedCallback(_duration); } void _removeTime() { if (_timeString.isEmpty) return; setState(() { _timeString = _timeString.substring(0, _timeString.length - 1); }); widget.onChangedCallback(_duration); } Duration get _duration { return Duration( hours: int.parse(_timeString.padLeft(4, '0').substring(0, 2)), minutes: int.parse(_timeString.padLeft(4, '0').substring(2, 4)), ); } ButtonStyle get _buttonTheme => ElevatedButton.styleFrom( textStyle: Theme.of(context).textTheme.displaySmall, ); }