Flutter picker library including date & time picker (with range setting), single item picker (for gender, ethnicity, education, constellation, age, height, weight, temperature, etc.), city address picker (province, city and county levels), multiple pickers and more... Welcome to Fork & PR to contribute your code, let's learn together!
Web Demo
flutter.eeaarr.cn (Try this if the above doesn't work)
1.Depend
dependencies:
flutter_pickers: ^2.2.02.Get
$ flutter packages get3.Install
import 'package:flutter_pickers/pickers.dart';Pickers.showAddressPicker()
- Supports three-level linkage
- Supports custom colors, sizes and other styles
- Supports displaying 'All' option
- Supports selecting only 2 levels (province and city)
- Supports querying city codes
- Real-time callback
||
|
|
|| :---------: | :------: |
|| Three-level Picker | Two-level Picker |
String initProvince = 'Sichuan', initCity = 'Chengdu', initTown = 'Shuangliu';
Widget _checkLocation() {
return InkWell(
onTap: () {
Pickers.showAddressPicker(
context,
initProvince: initProvince,
initCity: initCity,
initTown: initTown,
onConfirm: (p, c, t) {
setState(() {
initProvince = p;
initCity = c;
initTown = t;
});
},
);
},
child: Text('$initProvince - $initCity - $initTown'));
}- initTown: If not set or set to null, county/district level will not be displayed
AddressPicker.showPicker(
context,
initProvince: locations2[0],
initCity: locations2[1],
initTown: locations2[2],
showTitlebar: true,
menu: _headMenuView,
menuHeight: 36.0,
title: title,
cancelWidget: _cancelButton,
commitWidget: _commitButton,
headDecoration: headDecoration,
addAllItem: false,
textColor: Colors.white,
backgroundColor: Colors.grey[800],
onConfirm: (p, c, t) {},
);| Parameter | Description | Default |
|---|---|---|
| initProvince | Initialize province | '' |
| initCity | Initialize city | '' |
| initTown | Initialize county/district | '' |
| pickerStyle | See Styles | DefaultPickerStyle() |
| onChanged | Callback when picker changes, returns (String province, String city, String town) | null |
| onConfirm | Callback when picker confirms, returns (String province, String city, String town) | null |
| onCancel | Callback when picker cancels, returns (bool isCancel) whether closed by cancel button | null |
| addAllItem | Whether to add 'All' option for city and county/district | true |
/// Query city code by city name (in order)
List<String> cityCode = Address.getCityCodeByName(
provinceName: 'Sichuan',
cityName: 'Chengdu',
townName: 'Wuhou'
);
// returns [510000,510100,510104] or [510000,510000] or [510000] or []
/// Query city name by city code (in order)
List<String> cityName = Address.getCityNameByCode(
provinceCode: "510000",
cityCode: "510100",
townCode: "510104"
);
// returns [Sichuan, Chengdu, Jinjiang] or [Sichuan, Chengdu] or [Sichuan] or []Pickers.showSinglePicker() Check demo code here
- Single and multiple pickers support mixed data source of num and string
String initData = 'PHP';
Widget _demo() {
return InkWell(
onTap: () {
Pickers.showSinglePicker(
context,
data: ['PHP', 'JAVA', 'C++', 'Dart', 'Python', 'Go'],
selectData: initData,
onConfirm: (p, position) {
setState(() {
initData = p;
});
},
onChanged: (p) => debugPrint('Data changed: $p')
);
},
child: Text('$initData')
);
}| Parameter | Description | Default |
|---|---|---|
| data | Data source | null |
| selectData | Selected data | '' |
| pickerStyle | See Styles | DefaultPickerStyle() |
| onChanged | Callback when picker changes, returns (String data, int position) | null |
| onConfirm | Callback when picker confirms, returns (String data, int position) | null |
| onCancel | Callback when picker cancels, returns (bool isCancel) whether closed by cancel button | null |
Can be directly passed to data: PickerDataType.sex
- sex // Gender
- education // Education
- subject // Subject
- constellation // Constellation
- zodiac // Zodiac
- ethnicity // Ethnicity
Pickers.showMultiPicker() Check demo code here
final timeData = [
['AM', 'PM'],
List.generate(12, (index) => (index + 1).toString()).toList(),
List.generate(60, (index) => index.toString()).toList(),
List.generate(60, (index) => index.toString()).toList(),
];
void _showDemo(){
Pickers.showMultiPicker(
context,
data: timeData,
selectData: timeData2Select,
suffix: ['', 'h', 'm', 's'],
onConfirm: (p) {
debugPrint('Returned data types: ${p.map((x) => x.runtimeType).toList()}');
},
);
}| Parameter | Description | Default |
|---|---|---|
| data | Data source | null |
| selectData | Selected data | '' |
| suffix | Item suffix | null |
| pickerStyle | See Styles | DefaultPickerStyle() |
| onChanged | Callback when picker changes, returns (List data, List position) | null |
| onConfirm | Callback when picker confirms, returns (List data, List position) | null |
| onCancel | Callback when picker cancels, returns (bool isCancel) whether closed by cancel button | null |
Pickers.showMultiLinkPicker() Check demo code here
void _showPicker() {
var multiData = {
'a': {
'aa': [1, 'ww'],
'aaa': 10086
},
'b': ['bbb', 'bbbbb'],
'c': {
'cc': {
'ccc333': [111, 1111],
'cccc33': {
'ccccc4': 'Please star',
'ccc4-2': [4442, 44442, 442]
},
},
'cc2': ['ccc', 123],
'cc3': 'star to encourage'
}
};
Pickers.showMultiLinkPicker(
context,
data: multiData,
// Note: data types must match. For example, if 44442 is written as string '44442', it won't be found
// selectData: ['c', 'cc', 'cccc33', 'ccc4-2', 44442],
selectData: ['c', 'cc3'],
columnNum: 5,
suffix: ['', '', '', '', ''],
onConfirm: (List p) {
debugPrint('Returned data: ${p.join('、')}');
debugPrint('Returned data types: ${p.map((x) => x.runtimeType).toList()}');
},
);
}| Parameter | Description | Default |
|---|---|---|
| columnNum | Number of picker columns (required) | null |
| data | Data source | null |
- Similar to the multiple picker (no linkage) above, just modified 2 fields
- The outermost layer must be a map (since it's multiple, you need at least 2 columns)
- Map type indicates there's another column, if it's list or string/num, it means the last level has been reached
Pickers.showDatePicker() Check demo code here
- 16 modes 「Year-Month-Day-Hour-Minute-Second」
- Custom suffix
- Maximum|Minimum time
- Custom display style
Widget demo() {
return TextButton(
onPressed: () {
Pickers.showDatePicker(
context,
onConfirm: (p) {
print('Returned data: $p');
},
// onChanged: (p) => print(p),
);
},
child: Text('Demo')
);
}Pickers.showDatePicker(
context,
// Mode, see below
mode: DateMode.HMS,
// Suffix, default is Suffix.normal(), use Suffix() for empty
suffix: Suffix(hours: ' hour', minutes: ' min', seconds: ' sec'),
// Style, see styles below
pickerStyle: pickerStyle,
// Default selection
selectDate: PDuration(hour: 18, minute: 36, second: 36),
minDate: PDuration(hour: 12, minute: 38, second: 3),
maxDate: PDuration(hour: 12, minute: 40, second: 36),
onConfirm: (p) {
print('Returned data: $p');
},
// onChanged: (p) => print(p),
);| Parameter | Description | Default |
|---|---|---|
| mode | Time picker display style, 16 time styles | DateMode.YMD |
| selectData | PDuration() initialize selected time | Default now: PDuration.now() |
| minDate | PDuration() minimum time | PDuration(year: 1900) |
| maxDate | PDuration() maximum time | PDuration(year: 2100) |
| suffix | Unit corresponding to each column of time | Suffix.normal() |
| pickerStyle | See Styles | DefaultPickerStyle() |
| onChanged | Callback when picker changes, returns (PDuration data) | null |
| onConfirm | Callback when picker confirms, returns (PDuration data) | null |
| onCancel | Callback when picker cancels, returns (bool isCancel) whether closed by cancel button | null |
- PDuration()
selectDate, minDate, maxDate and returned data type are all PDuration()
// Can customize year, month, day, hour, minute, second
PDuration(year: 2020, month: 1, day: 4, hour: 12, minute: 40, second: 36);
// Set DateTime type
PDuration.parse(DateTime.parse('20210101'));
PDuration.now();- DateMode Time picker display styles
/// Time picker display styles
enum DateMode {
/// 【yyyy-MM-dd HH:mm:ss】Year-Month-Day-Hour-Minute-Second
YMDHMS,
/// 【yyyy-MM-dd HH:mm】Year-Month-Day-Hour-Minute
YMDHM,
/// 【yyyy-MM-dd HH】Year-Month-Day-Hour
YMDH,
/// 【yyyy-MM-dd】Year-Month-Day
YMD,
/// 【yyyy-MM】Year-Month
YM,
/// 【yyyy】Year
Y,
/// 【MM-dd HH:mm:ss】Month-Day-Hour-Minute-Second
MDHMS,
/// 【MM-dd HH:mm】Month-Day-Hour-Minute
MDHM,
/// 【MM-dd HH:mm】Month-Day-Hour
MDH,
/// 【MM-dd】Month-Day
MD,
/// 【HH:mm:ss】Hour-Minute-Second
HMS,
/// 【HH:mm】Hour-Minute
HM,
/// 【mm:ss】Minute-Second
MS,
/// 【ss】Second
S,
/// 【MM】Month
M,
/// 【HH】Hour
H
}- If date is used, selectData needs to pass in year, otherwise it cannot be calculated. If not provided, defaults to current year
- When there's only single column data, min|max restrictions don't create linkage, only restrict single column items. For example, maxDate: day=3, minDate: day=10, then day only shows between 3-10
- If minDate: year: 2020, month: 2, day: 10, only dates after February 10, 2020 are displayed
- minDate|maxDate's YMD and HMS have no linkage! No linkage! For example, setting maxDate: year: 2020, month: 2, day: 10, hour: 8, does not mean times after 8 o'clock on February 10, 2020
style_picker_page.dart Check demo code here default_style.dart source code
- The following 4 styles are encapsulated using the PickerStyle class
- All have built-in dark mode, such as NoTitleStyle.dark()
- Except NoTitleStyle, other styles can accept parameters:
- haveRadius: Whether to have rounded corners
- title: Title
- color: Confirm button color
||
|
|
|| :----------------------------------------------------------: | :----------------------------------------------------------: |
|| Default Style: DefaultPickerStyle() | Default Style (Dark): DefaultPickerStyle.dark() |
|| | |
||
|
|
|| No Title Style: NoTitleStyle() | No Title Style (Dark): NoTitleStyle.dark() |
|| | |
||
|
|
|| Close Button Style: ClosePickerStyle() | Close Button Style (Dark): ClosePickerStyle.dark() |
|| | |
||
|
|
|| Raised Button Style: RaisedPickerStyle() | Raised Button Style (Dark): RaisedPickerStyle.dark() |
style_picker_page.dart Check demo code here picker_style.dart Style base class
/// [showTitleBar] Whether to show header (widgets above picker), default: true
/// [menu] Menu widget between header and picker, default null (not displayed)
/// [title] Title in the middle of header, default SizedBox() (not displayed)
/// [pickerHeight] Overall height of picker below, fixed height: 220.0
/// [pickerTitleHeight] Overall height of title area above picker (confirm/cancel), fixed height: 44.0
/// [pickerItemHeight] Height of each selected item in picker: 40.0
/// [menuHeight] Menu height between header and picker, fixed height: 36.0
/// [cancelButton] Cancel button in header
/// [commitButton] Confirm button in header
/// [textColor] Text color of picker, default black
/// [textSize] Text size of picker
/// [backgroundColor] Background color of picker, default white
/// [headDecoration] Decoration of header container, default: BoxDecoration(color: Colors.white)
/// [itemOverlay] Overlay component for items, can customize selected style [See double line style reference](https://github.com/longer96/flutter_pickers/issues/12)
class PickerStyle {}flutter_pickers uses the MIT license, see LICENSE file for details.

















