Flutter:CupertinoDatePicker不好使,自己撸一个小时与分钟的时间选择器
站长
· 阅读数 6
最近在自己的Flutter项目中需要使用iOS风格的小时与分钟的时间选择器。
本来开箱即用的CupertinoDatePicker就基本上可以满足需求,奈何项目里大部分都是黑色背景,而CupertinoDatePicker无法设置文本颜色,结果就是一团黑,根本看不清楚选择的什么时间。
借着大神引领的路,自己撸一个就很简单了。
下面代码只是最最简单的例子,大家可以借鉴其中,自己进行自定义:
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,
/// 是否放大
useMagnifier: 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;
}
}