Flutter链式选择器插件linkage_picker的使用
Flutter链式选择器插件linkage_picker的使用
linkage_picker
是一个基于 CupertinoPicker 风格的链式选择器组件。它提供了 DatePicker
实现,并且你可以通过扩展 LinkagePickerWidget
来实现更复杂的场景。
DatePicker
DatePicker
是一个预设的链式选择器。
DatePicker(
start: DateTime(2000, today.month, today.day),
end: DateTime(2050, today.month, today.day),
date: date,
)
你也可以将 DatePicker
以底部弹出框的形式展示:
DatePicker(
...
).showAsBottomSheet(context)
或者将其嵌入到其他组件中:
ValueListenableBuilder<bool>(
valueListenable: showPicker,
builder: (context, value, _) {
return value
? Column(
mainAxisSize: MainAxisSize.min,
children: [
DatePicker(
...,
onControllerCreated: (controller) {
this.controller = controller;
},
),
TextButton(
onPressed: () {
showPicker.value = false;
final result = controller.result;
if (result != null) {
content.value = DateFormat('yyyy-MM-dd').format(result);
}
},
child: const Text('确认')),
],
)
: const SizedBox.shrink();
})
CustomPicker
你可以通过扩展 LinkagePickerWidget
来创建自定义的链式选择器。
class CustomPicker extends LinkagePickerWidget<CustomData, String> {
CustomPicker()
: super(
maxLevel: LinkagePickerLevel.second,
dataBuilder: (level, parent) {
return switch (level) {
LinkagePickerLevel.first => LinkagePickerData<CustomData>[...],
LinkagePickerLevel.second => LinkagePickerData<CustomData>[...],
_ => throw UnimplementedError(),
};
},
equalizer: (level, value1, value2) {
return switch (level) {
_ => (value1 as CustomData).equals(value2 as CustomData),
};
},
resultConverter: (selection) {
final getResultString(selection.first, selection.last);
},
conflictResolver: (level, previous, currents) {
return switch (level) {
LinkagePickerLevel.first => null,
LinkagePickerLevel.second =>
(previous as CustomData).copyWith(...),
_ => throw UnimplementedError(),
};
},
initialValue: <CustomData>[...],
pickerStyle: LinkagePickerStyle(
itemBuilder: (level, data, selected) {
switch (level) {
case LinkagePickerLevel.first:
return buildFirstPickerItem(data, selected);
case LinkagePickerLevel.second:
return buildSecondPickerItem(data, selected);
default:
throw UnimplementedError();
}
},
),
);
}
LinkagePickerWidget<T,R>
<T>
: 数据源值的类型<R>
: 结果的类型maxLevel
: 选择器的最大层级dataBuilder
: 返回当前层级及其父数据的数据源equalizer
: 告诉组件在当前层级两个值是否相等resultConverter
: 将结果转换为你想要的类型conflictResolver
: 将选择器选定的结果转换为导航结果initialValue
: 选择器的初始值pickerStyle
: 自定义选择器的样式onControllerCreated
: 控制器创建时的回调
LinkagePickerStyle
diameterRatio
: 与CupertinoPicker.diameterRatio
相同itemExtent
: 与CupertinoPicker.itemExtent
相同backgroundColor
: 与CupertinoPicker.backgroundColor
相同offAxisFraction
: 与CupertinoPicker.offAxisFraction
相同squeeze
: 与CupertinoPicker.squeeze
相同useMagnifier
: 与CupertinoPicker.useMagnifier
相同magnification
: 与CupertinoPicker.magnification
相同selectionOverlay
: 与CupertinoPicker.selectionOverlay
相同heightRatio
: 选择器高度与项目高度的比例itemBuilder
: 自定义选择器项目的样式
完整示例代码
import 'package:example/picker_field/picker_field_custom_color_palette.dart';
import 'package:example/picker_field/picker_field_custom_time.dart';
import 'package:example/picker_field/picker_field_date_bottom_sheet.dart';
import 'package:example/picker_field/picker_field_date.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Linkage Picker Example'),
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
pickerExampleSegment(
'DatePicker',
const PickerFieldDate(),
),
pickerExampleSegment(
'DatePicker[BottomSheet]',
PickerFieldDateBottomSheet(context),
),
pickerExampleSegment(
'CustomPicker[Time]',
PickerFieldCustomTime(context),
),
pickerExampleSegment(
'CustomPicker[ColorPalette]',
PickerFieldCustomColorPalette(context),
),
],
),
),
),
);
}
Widget pickerExampleSegment(String title, Widget child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 8),
child,
const SizedBox(height: 20),
],
);
}
}
更多关于Flutter链式选择器插件linkage_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter链式选择器插件linkage_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
linkage_picker
是一个用于 Flutter 的链式选择器插件,通常用于实现类似于省市区选择、日期选择等多级联动的选择器。它可以帮助用户通过多级联动的方式选择数据。
以下是如何在 Flutter 项目中使用 linkage_picker
插件的步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 linkage_picker
插件的依赖:
dependencies:
flutter:
sdk: flutter
linkage_picker: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入插件
在需要使用 linkage_picker
的 Dart 文件中导入插件:
import 'package:linkage_picker/linkage_picker.dart';
3. 使用 LinkagePicker
LinkagePicker
是一个可以自定义的多级联动选择器。你可以通过传递数据和配置来使用它。
示例:省市区选择器
假设你有一个包含省市区数据的数据源,你可以通过以下方式使用 LinkagePicker
:
class ProvinceCityAreaPicker extends StatefulWidget {
@override
_ProvinceCityAreaPickerState createState() => _ProvinceCityAreaPickerState();
}
class _ProvinceCityAreaPickerState extends State<ProvinceCityAreaPicker> {
List<LinkageItem> _data = [];
@override
void initState() {
super.initState();
// 模拟省市区数据
_data = [
LinkageItem(name: '北京', children: [
LinkageItem(name: '北京市', children: [
LinkageItem(name: '东城区'),
LinkageItem(name: '西城区'),
]),
]),
LinkageItem(name: '上海', children: [
LinkageItem(name: '上海市', children: [
LinkageItem(name: '黄浦区'),
LinkageItem(name: '徐汇区'),
]),
]),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('省市区选择器'),
),
body: Center(
child: LinkagePicker(
data: _data,
onChanged: (List<LinkageItem> selectedItems) {
// 当用户选择时回调
print('Selected: ${selectedItems.map((item) => item.name).toList()}');
},
),
),
);
}
}
LinkageItem
结构
LinkageItem
是 linkage_picker
中用于表示每一级数据的类。它包含 name
和 children
属性:
class LinkageItem {
String name;
List<LinkageItem> children;
LinkageItem({required this.name, this.children = const []});
}
自定义样式
你可以通过 LinkagePicker
的 style
参数来自定义选择器的样式:
LinkagePicker(
data: _data,
onChanged: (List<LinkageItem> selectedItems) {
print('Selected: ${selectedItems.map((item) => item.name).toList()}');
},
style: LinkagePickerStyle(
backgroundColor: Colors.white,
itemTextStyle: TextStyle(color: Colors.black),
selectedItemTextStyle: TextStyle(color: Colors.blue),
dividerColor: Colors.grey,
),
);