I recently needed to use ios-style hour and minute time pickers in my Flutter project.
So, CupertinoDatePicker, right out of the box, would be able to do that, but most of the projects in cupertino have a black background. So, CupertinoDatePicker can’t set the color of the text.
I happened to read an article about ListWheelViewport recently
It’s easy to masturbate yourself by the way that god leads.
The following code is the simplest example, which you can use to customize your own:
class CustomDatePicker extends StatefulWidget { CustomDatePicker({this.timeCallback, Key key}) : super(key: key); final ValueChanged<String> timeCallback; @override _CustomDatePickerState createState() => _CustomDatePickerState(); } class _CustomDatePickerState extends State<CustomDatePicker> { final _hours = List.generate(24, (i) => i.timeFormat); final _minutes = List.generate(60, (i) => i.timeFormat); var _hourViewIndex = 0; var _minuteViewIndex = 0; FixedExtentScrollController _hourController; FixedExtentScrollController _minuteController; @override void initState() { super.initState(); _nowTimeSetting(); } @override Widget build(BuildContext context) { return Container( child: Stack( children: [ Row( children: [ _hourView(), _minuteView(), ], ), Positioned( left: 16, right: 16, top: 68, child: Divider(), ), Positioned( left: 16, right: 16, top: 118, child: Divider(), ), ], ), ); } Widget _hourView() { return _timeWheel(times: _hours, isHour: true, controller: _hourController); } Widget _minuteView() { return _timeWheel( times: _minutes, isHour: false, controller: _minuteController); } Widget _timeWheel( {List<String> times, bool isHour, FixedExtentScrollController controller}) { return Flexible( child: Container( height: 190, child: ListWheelScrollView.useDelegate( controller: controller, childDelegate: ListWheelChildLoopingListDelegate( children: Times.map ((number) => _buildItem(number),).tolist (),), perspective: 0.006, itemExtent: 49, True, // magnIFICATION: 1.2, onSelectedItemChanged: (index) {if (isHour) {_hourViewIndex = index; } else { _minuteViewIndex = index; } final time = _hours[_hourViewIndex] + ":" + _minutes[_minuteViewIndex]; widget.timeCallback(time); },),),); } Widget _buildItem(String time) { return Container( key: ValueKey(time), alignment: Alignment.center, height: 50, color: Color(0xFF), child: Text( time, textDirection: TextDirection.rtl, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 23, color: Colors.white, ), ), ); } void _nowTimeSetting() { final nowTime = DateTime.now(); final nowHour = nowTime.hour.timeFormat; final nowMinute = nowTime.minute.timeFormat; _hourViewIndex = _hours.indexOf(nowHour); _minuteViewIndex = _minutes.indexOf(nowMinute); _hourController = FixedExtentScrollController(initialItem: _hourViewIndex); _minuteController = FixedExtentScrollController(initialItem: _minuteViewIndex); } @override void dispose() { _hourController.dispose(); _minuteController.dispose(); super.dispose(); } } extension on int { String get timeFormat { var string = this.toString(); return string.length == 2 ? string : "0" + string; }}Copy the code