Flutter时间选择器插件progressive_time_picker的使用
Flutter时间选择器插件progressive_time_picker的使用
简介
progressive_time_picker
是一个可高度自定义的时间选择器插件,适用于Flutter应用程序。它支持多个平台(Android、iOS、Web、Mac、Linux、Windows),并允许用户根据需求选择特定的时间范围。该插件提供了丰富的自定义选项,包括12小时和24小时格式的时钟数字显示、禁用特定时间范围等功能。
主要特性
- 支持单个或同时选择两个时间点。
- 提供了易于使用的自定义装饰选项。
- 支持12小时和24小时格式,并且可以完全自定义。
- 允许禁用特定的时间段以增加控制力。
预览
以下是progressive_time_picker
的一些预览图:
带有禁用时间段的时间选择器:
基本用法
首先,在项目中导入此包:
import 'package:progressive_time_picker/progressive_time_picker.dart';
然后以最简单的方式添加到你的界面中:
最简单的用法
TimePicker(
initTime: PickedTime(h: 0, m: 0),
endTime: PickedTime(h: 8, m: 0),
onSelectionChange: (start, end, isDisableRange) =>
print('onSelectionChange => init : ${start.h}:${start.m}, end : ${end.h}:${end.m}, isDisableRangeRange: $isDisableRange'),
onSelectionEnd: (start, end, isDisableRange) =>
print('onSelectionEnd => init : ${start.h}:${start.m}, end : ${end.h}:${end.m}, isDisableRangeRange: $isDisableRange'),
);
包含禁用时间段的用法
TimePicker(
initTime: PickedTime(h: 0, m: 0),
endTime: PickedTime(h: 8, m: 0),
disabledRanges: [
DisabledRange(
initTime: PickedTime(h: 12, m: 0),
endTime: PickedTime(h: 20, m: 0),
),
],
disabledRangesColor: Colors.grey,
disabledRangesErrorColor: Colors.red,
onSelectionChange: (start, end, isDisableRange) => print(
'onSelectionChange => init : ${start.h}:${start.m}, end : ${end.h}:${end.m}, isDisableRangeRange: $isDisableRange'),
onSelectionEnd: (start, end, isDisableRange) => print(
'onSelectionEnd => init : ${start.h}:${start.m}, end : ${end.h}:${end.m}, isDisableRangeRange: $isDisableRange'),
);
参数说明
TimePicker 必填参数
参数 | 描述 |
---|---|
PickedTime initTime |
初始选择的时间 |
PickedTime endTime |
结束选择的时间 |
onSelectionChange |
当初始时间和结束时间发生变化时调用的回调函数 |
onSelectionEnd |
当初始时间和结束时间的选择完成时调用的回调函数 |
TimePicker 可选参数
参数 | 默认值 | 描述 |
---|---|---|
double height |
220 | 画布的高度 |
double width |
220 | 画布的宽度 |
int primarySectors |
0 | 要绘制的主要扇区数量 |
int secondarySectors |
0 | 要绘制的次要扇区数量 |
Widget child |
Container | 将放置在圆圈内部的小部件 |
TimePickerDecoration decoration |
- | 用于装饰TimePicker 小部件 |
bool isInitHandlerSelectable |
true | 是否启用或禁用初始处理器的选择 |
bool isEndHandlerSelectable |
true | 是否启用或禁用结束处理器的选择 |
bool isSelectableHandlerMoveAble |
true | 是否启用或禁用未被选中的处理器移动 |
List<DisabledRange> |
null | 用于禁用选择范围,如果为null,则没有禁用的时间范围 |
Color disabledRangesColor |
Colors.grey | 定义禁用范围的颜色 |
Color disabledRangesErrorColor |
Colors.red | 定义禁用范围错误的颜色 |
bool drawInitHandlerOnTop |
false | 设置优先绘制初始处理器还是结束处理器 |
TimePickerDecoration 必填参数
参数 | 描述 |
---|---|
TimePickerSweepDecoration sweepDecoration |
用于装饰扫过部分或初始与结束点之间的区域 |
TimePickerHandlerDecoration initHandlerDecoration |
用于装饰时间选择器的初始或结束处理器 |
TimePickerHandlerDecoration endHandlerDecoration |
用于装饰时间选择器的初始或结束处理器 |
TimePickerDecoration 可选参数
参数 | 默认值 | 描述 |
---|---|---|
Color baseColor |
cyanAccent | 定义选择器的背景颜色 |
double pickerBaseCirclePadding |
0.0 | 为选择器的基本或外圈添加额外的填充 |
TimePickerSectorDecoration primarySectorsDecoration |
- | 用于装饰时间选择器的主要扇区 |
TimePickerSectorDecoration secondarySectorsDecoration |
- | 用于装饰时间选择器的次要扇区 |
TimePickerClockNumberDecoration clockNumberDecoration |
- | 提供应用于内部时钟数字的装饰选项 |
SystemMouseCursor mouseCursor |
- | 用于设置PanGestureRecognizer 的系统鼠标指针 |
示例代码
下面是一个完整的示例代码,展示了如何在应用中集成progressive_time_picker
:
import 'dart:developer' as dev;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart' as intl;
import 'package:progressive_time_picker/progressive_time_picker.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then(
(value) => runApp(MyApp()),
);
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ClockTimeFormat clockTimeFormat = ClockTimeFormat.twentyFourHours;
ClockIncrementTimeFormat clockIncrementTimeFormat = ClockIncrementTimeFormat.fiveMin;
PickedTime inBedTime = PickedTime(h: 0, m: 0);
PickedTime outBedTime = PickedTime(h: 8, m: 0);
PickedTime intervalBedTime = PickedTime(h: 0, m: 0);
PickedTime disabledInitTime = PickedTime(h: 12, m: 0);
PickedTime disabledEndTime = PickedTime(h: 20, m: 0);
double sleepGoal = 8.0;
bool isSleepGoal = false;
bool? validRange = true;
@override
void initState() {
super.initState();
isSleepGoal = (sleepGoal >= 8.0) ? true : false;
intervalBedTime = formatIntervalTime(
init: inBedTime,
end: outBedTime,
clockTimeFormat: clockTimeFormat,
clockIncrementTimeFormat: clockIncrementTimeFormat,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF141925),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Sleep Time',
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
TimePicker(
initTime: inBedTime,
endTime: outBedTime,
disabledRanges: [
DisabledRange(
initTime: disabledInitTime,
endTime: disabledEndTime,
),
],
disabledRangesColor: Colors.grey,
disabledRangesErrorColor: Colors.red,
height: 260.0,
width: 260.0,
onSelectionChange: _updateLabels,
onSelectionEnd: (start, end, isDisableRange) => dev.log(
'onSelectionEnd => init : ${start.h}:${start.m}, end : ${end.h}:${end.m}, isDisableRange: $isDisableRange'),
primarySectors: clockTimeFormat.value,
secondarySectors: clockTimeFormat.value * 2,
decoration: TimePickerDecoration(
baseColor: Color(0xFF1F2633),
pickerBaseCirclePadding: 15.0,
sweepDecoration: TimePickerSweepDecoration(
pickerStrokeWidth: 30.0,
pickerColor: isSleepGoal ? Color(0xFF3CDAF7) : Colors.white,
showConnector: true,
),
initHandlerDecoration: TimePickerHandlerDecoration(
color: Color(0xFF141925),
shape: BoxShape.circle,
radius: 12.0,
icon: Icon(
Icons.power_settings_new_outlined,
size: 20.0,
color: Color(0xFF3CDAF7),
),
),
endHandlerDecoration: TimePickerHandlerDecoration(
color: Color(0xFF141925),
shape: BoxShape.circle,
radius: 12.0,
icon: Icon(
Icons.notifications_active_outlined,
size: 20.0,
color: Color(0xFF3CDAF7),
),
),
primarySectorsDecoration: TimePickerSectorDecoration(
color: Colors.white,
width: 1.0,
size: 4.0,
radiusPadding: 25.0,
),
secondarySectorsDecoration: TimePickerSectorDecoration(
color: Color(0xFF3CDAF7),
width: 1.0,
size: 2.0,
radiusPadding: 25.0,
),
clockNumberDecoration: TimePickerClockNumberDecoration(
defaultTextColor: Colors.white,
defaultFontSize: 12.0,
scaleFactor: 2.0,
showNumberIndicators: true,
clockTimeFormat: clockTimeFormat,
clockIncrementTimeFormat: clockIncrementTimeFormat,
),
),
child: Padding(
padding: const EdgeInsets.all(62.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${intl.NumberFormat('00').format(intervalBedTime.h)}Hr ${intl.NumberFormat('00').format(intervalBedTime.m)}Min',
style: TextStyle(
fontSize: 12.0,
color: isSleepGoal ? Color(0xFF3CDAF7) : Colors.white,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
Container(
width: 300.0,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0xFF1F2633),
borderRadius: BorderRadius.circular(25.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
isSleepGoal
? "Above Sleep Goal (>=8) 😇"
: 'below Sleep Goal (<=8) 😴',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_timeWidget(
'BedTime',
inBedTime,
Icon(
Icons.power_settings_new_outlined,
size: 25.0,
color: Color(0xFF3CDAF7),
),
),
_timeWidget(
'WakeUp',
outBedTime,
Icon(
Icons.notifications_active_outlined,
size: 25.0,
color: Color(0xFF3CDAF7),
),
),
],
),
Text(
validRange == true
? "Working hours ${intl.NumberFormat('00').format(disabledInitTime.h)}:${intl.NumberFormat('00').format(disabledInitTime.m)} to ${intl.NumberFormat('00').format(disabledEndTime.h)}:${intl.NumberFormat('00').format(disabledEndTime.m)}"
: "Please schedule according working time!",
style: TextStyle(
fontSize: 16.0,
color: validRange == true ? Colors.white : Colors.red,
),
),
],
),
);
}
Widget _timeWidget(String title, PickedTime time, Icon icon) {
return Container(
width: 150.0,
decoration: BoxDecoration(
color: Color(0xFF1F2633),
borderRadius: BorderRadius.circular(25.0),
),
child: Padding(
padding: const EdgeInsets.all(25.0),
child: Column(
children: [
Text(
'${intl.NumberFormat('00').format(time.h)}:${intl.NumberFormat('00').format(time.m)}',
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 15),
Text(
title,
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 16,
),
),
SizedBox(height: 10),
icon,
],
),
),
);
}
void _updateLabels(PickedTime init, PickedTime end, bool? isDisableRange) {
inBedTime = init;
outBedTime = end;
intervalBedTime = formatIntervalTime(
init: inBedTime,
end: outBedTime,
clockTimeFormat: clockTimeFormat,
clockIncrementTimeFormat: clockIncrementTimeFormat,
);
isSleepGoal = validateSleepGoal(
inTime: init,
outTime: end,
sleepGoal: sleepGoal,
clockTimeFormat: clockTimeFormat,
clockIncrementTimeFormat: clockIncrementTimeFormat,
);
setState(() {
validRange = isDisableRange;
});
}
}
以上是关于progressive_time_picker
插件的详细介绍和使用方法,希望对您有所帮助!如果您有任何问题或建议,请随时联系开发者团队。
更多关于Flutter时间选择器插件progressive_time_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter时间选择器插件progressive_time_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用progressive_time_picker
插件的示例代码。progressive_time_picker
是一个允许用户选择时间的Flutter插件,它提供了一个直观且用户友好的界面。
首先,你需要在你的pubspec.yaml
文件中添加该插件的依赖:
dependencies:
flutter:
sdk: flutter
progressive_time_picker: ^x.y.z # 请将x.y.z替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter应用中使用ProgressiveTimePicker
。以下是一个完整的示例代码,展示了如何在一个简单的Flutter应用中集成和使用progressive_time_picker
。
import 'package:flutter/material.dart';
import 'package:progressive_time_picker/progressive_time_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime? selectedTime;
void _selectTime() async {
final DateTime? picked = await showProgressiveTimePicker(
context: context,
locale: Localizations.localeOf(context),
initialTime: selectedTime ?? DateTime.now(),
theme: ProgressivePickerThemeData.lightTheme(), // 可以选择使用lightTheme()或darkTheme()
);
if (picked != null && picked != selectedTime) {
setState(() {
selectedTime = picked;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Progressive Time Picker Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
selectedTime == null
? 'No time selected'
: 'Selected Time: ${selectedTime!.toLocal()}',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _selectTime,
child: Text('Select Time'),
),
],
),
),
);
}
}
解释
-
依赖添加:
- 在
pubspec.yaml
中添加progressive_time_picker
的依赖。
- 在
-
导入包:
- 在你的Dart文件中导入
progressive_time_picker
包。
- 在你的Dart文件中导入
-
创建UI:
- 使用
Scaffold
来创建一个简单的页面布局。 - 使用
Text
来显示当前选择的时间(如果没有选择时间,则显示"No time selected")。 - 使用
ElevatedButton
来触发时间选择器。
- 使用
-
选择时间:
- 使用
showProgressiveTimePicker
方法来显示时间选择器。 - 当用户选择时间后,更新
selectedTime
状态。
- 使用
-
样式和主题:
ProgressivePickerThemeData.lightTheme()
或ProgressivePickerThemeData.darkTheme()
可以用来设置时间选择器的主题。
这个示例展示了如何在Flutter应用中集成和使用progressive_time_picker
插件。你可以根据需要进行进一步的自定义和扩展。