Flutter轮盘选择插件fl_list_wheel的使用
Flutter轮盘选择插件fl_list_wheel的使用
在本指南中,我们将详细介绍如何使用 fl_list_wheel
插件来创建轮盘选择器。该插件提供了多种类型的轮盘选择器,包括日期选择器、时间选择器和多列表联动选择器等。
运行 Web 示例
要运行 Web 示例,请访问以下链接:
所有组件
以下是 fl_list_wheel
中所有可用的组件:
final picker = [
/// FlListWheel
FlListWheel.builder(),
/// FlListWheel
FlListWheel.count(),
/// FlListWheelState
FlListWheelState.builder(),
/// FlListWheelState
FlListWheelState.count(),
/// 日期选择器
DatePicker(),
/// 日期时间选择器
DateTimePicker(),
/// 多列表联动选择器
MultiListLinkagePicker(),
/// 多列表轮盘联动选择器
MultiListWheelLinkagePicker(),
/// 单列表选择器
SingleListPicker(),
/// 单列表轮盘选择器
SingleListWheelPicker(),
];
如果使用 show 方法必须初始化以下两个方法
如果你打算使用 show
方法,你必须初始化以下两个方法:
[@override](/user/override)
void initState() {
super.initState();
FlListWheel.push = (Widget picker) {
return showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(4))),
builder: (_) => picker);
};
FlListWheel.pop = (dynamic value) {
return Navigator.of(context).pop(value);
};
}
FlListWheel
和 FlListWheelState
FlListWheelState
可以自己管理 FixedExtentScrollController
init 和 dispose
Widget build() {
return ListView(children: [
FlListWheel.builder(
onSelectedItemChanged: (_) {
debugPrint('ListWheel.builder : $_');
},
itemBuilder: (_, int index) => Text(numberList[index]),
itemCount: numberList.length),
FlListWheel.count(
options: const WheelOptions(),
onSelectedItemChanged: (_) {
debugPrint('ListWheel.count : $_');
},
children: numberList.map((item) => Text(item)).toList()),
FlListWheelState(
count: numberList.length,
initialItem: 5,
builder: (_) =>
FlListWheel.builder(
controller: _,
onSelectedItemChanged: (_) {
debugPrint('ListWheelState.builder : $_');
},
itemBuilder: (_, int index) => Text(numberList[index]),
itemCount: numberList.length)),
FlListWheelState(
initialItem: 5,
count: numberList.length,
builder: (_) =>
FlListWheel.count(
controller: _,
options: const WheelOptions(),
onSelectedItemChanged: (_) {
debugPrint('ListWheelState.builder : $_');
},
children: numberList.map((item) => Text(item)).toList()))
]);
}
日期选择器
void func() {
DatePicker().show();
}
Widget build() {
return DatePicker(
height: 200,
startDate: defaultDate.subtract(const Duration(days: 365)),
endDate: defaultDate.add(const Duration(days: 365)),
defaultDate: defaultDate,
options: options,
onChanged: (DateTime dateTime) {
debugPrint(dateTime.toString());
},
itemBuilder: (String text) => Text(text, style: const TextStyle(fontSize: 16)),
unit: const DatePickerUnit.yd(year: '年', day: '日', month: '月'));
}
日期时间选择器
void func() {
DateTimePicker().show();
}
Widget build() {
return DateTimePicker(
options: BasePickerOptions<DateTime>().merge(PickerOptions<DateTime>(
contentPadding: const EdgeInsets.symmetric(horizontal: 12),
verifyConfirm: (DateTime? dateTime) {
debugPrint(dateTime?.toString() ?? 'verifyConfirm');
return true;
},
verifyCancel: (DateTime? dateTime) {
debugPrint(dateTime?.toString() ?? 'verifyCancel');
return true;
})),
startDate: defaultDate.subtract(const Duration(days: 365)),
defaultDate: defaultDate,
endDate: defaultDate.add(const Duration(days: 365)),
onChanged: (DateTime dateTime) {
debugPrint(dateTime.toString());
},
height: 200,
unit: const DateTimePickerUnit.yd(year: '年', month: '', day: ''));
}
区域选择器
void func() {
Future<void> pick() async {
final items = mapToLinkageItems(areaDataMap);
final position = await MultiListWheelLinkagePicker<String>(
wheelOptions: const WheelOptions.cupertino(),
height: 200,
onChanged: (List<int> index) {
debugPrint('AreaPicker onChanged= $index');
},
onValueChanged: (List<String> list) {
debugPrint('AreaPicker onValueChanged= $list');
},
items: mapToLinkageItems(areaDataMap),
isScrollable: false)
.show();
if (position == null) return;
List<String> value = [];
List<PickerLinkageItem> resultList = items;
position.map((index) {
if (index < resultList.length) {
value.add(resultList[index].value);
resultList = resultList[index].children;
}
}).toList();
debugPrint(value.toString());
}
}
Widget build() {
return MultiListWheelLinkagePicker<String>(
options: options,
wheelOptions: const WheelOptions.cupertino(),
height: 200,
onChanged: (List<int> index) {
debugPrint('AreaPicker onChanged= $index');
},
onValueChanged: (List<String> list) {
debugPrint('AreaPicker onValueChanged= $list');
},
items: mapToLinkageItems(areaDataMap),
isScrollable: false);
}
完整示例代码
以下是一个完整的示例代码,展示了如何使用 fl_list_wheel
插件来创建一个简单的轮盘选择器页面。
import 'package:device_preview_minus/device_preview_minus.dart';
import 'package:example/src/list_wheel_page.dart';
import 'package:example/src/picker/area_picker.dart';
import 'package:example/src/picker/date_picker.dart';
import 'package:example/src/picker/date_time_picker.dart';
import 'package:example/src/picker/multi_list_linkage_picker.dart';
import 'package:example/src/picker/multi_list_wheel_linkage_picker.dart';
import 'package:example/src/picker/multi_list_wheel_picker.dart';
import 'package:example/src/picker/single_list_picker.dart';
import 'package:example/src/picker/single_list_wheel_picker.dart';
import 'package:fl_list_wheel/fl_list_wheel.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(DevicePreview(
enabled: kIsWeb,
defaultDevice: Devices.ios.iPhone13Mini,
builder: (context) => MaterialApp(
locale: DevicePreview.locale(context),
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
builder: (BuildContext context, Widget? child) {
return DevicePreview.appBuilder(context, child);
},
home: Scaffold(
appBar: AppBar(title: const Text('FlScrollView')),
body: const HomePage()))));
}
const List<Color> colorList = [
...Colors.accents,
...Colors.primaries,
];
class AppBarText extends AppBar {
AppBarText(String text, {super.key})
: super(
elevation: 0,
title: Text(text,
style:
const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
centerTitle: true);
}
class ElevatedText extends StatelessWidget {
const ElevatedText(this.text, {this.onTap, super.key});
final VoidCallback? onTap;
final String text;
[@override](/user/override)
Widget build(BuildContext context) {
final current = ElevatedButton(onPressed: onTap, child: Text(text));
if (defaultTargetPlatform == TargetPlatform.android &&
defaultTargetPlatform == TargetPlatform.iOS) return current;
return Padding(padding: const EdgeInsets.all(10), child: current);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
[@override](/user/override)
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
[@override](/user/override)
void initState() {
super.initState();
FlListWheel.push = (Widget picker) {
return showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(4))),
builder: (_) => picker);
};
FlListWheel.pop = (dynamic value) {
return Navigator.of(context).pop(value);
};
}
[@override](/user/override)
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.symmetric(horizontal: 10),
children: [
ElevatedText('FlListWheel', onTap: () {
push(const ListWheelPage());
}),
ElevatedText('DatePicker', onTap: () {
push(DatePickerPage());
}),
ElevatedText('DateTimePicker', onTap: () {
push(DateTimePickerPage());
}),
ElevatedText('AreaPicker', onTap: () {
push(const AreaPickerPage());
}),
ElevatedText('MultiListLinkagePicker', onTap: () {
push(const MultiListLinkagePickerPage());
}),
ElevatedText('MultiListWheelPicker', onTap: () {
push(const MultiListWheelPickerPage());
}),
ElevatedText('MultiListWheelLinkagePicker', onTap: () {
push(const MultiListWheelLinkagePickerPage());
}),
ElevatedText('SingleListPicker', onTap: () {
push(const SingleListPickerPage());
}),
ElevatedText('SingleListWheelPicker', onTap: () {
push(const SingleListWheelPickerPage());
}),
ElevatedText('show CustomPicker', onTap: customPicker),
]);
}
Future<void> customPicker() async {
Widget picker = CustomPicker<String>(
options: PickerOptions<String>(
decoration: const BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.vertical(top: Radius.circular(10))),
verifyConfirm: (String? value) {
debugPrint('verifyConfirm $value');
return true;
},
verifyCancel: (String? value) {
debugPrint('verifyCancel $value');
return true;
},
title: Container(
alignment: Alignment.center,
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 2),
decoration: BoxDecoration(
color: Colors.lightBlue,
borderRadius: BorderRadius.circular(6)),
child: const Text('Title'))),
content: Container(
height: 300,
alignment: Alignment.center,
color: Colors.blue.withOpacity(0.2),
child: const Text('showCustomPicker',
style: TextStyle(color: Colors.black))),
confirmTap: () {
return 'Confirm';
},
cancelTap: () {
return 'Cancel';
});
final String? data = await showModalBottomSheet<String?>(
context: context, builder: (_) => picker);
debugPrint(data);
}
void push(Widget widget) {
showCupertinoModalPopup(context: context, builder: (_) => widget);
}
}
class ExtendedScaffold extends StatelessWidget {
const ExtendedScaffold(
{super.key, this.appBar, this.children = const [], this.padding});
final AppBar? appBar;
final List<Widget> children;
final EdgeInsetsGeometry? padding;
[@override](/user/override)
Widget build(BuildContext context) {
Widget current = ListView(children: children);
if (padding != null) {
current = Padding(padding: padding!, child: current);
}
return Scaffold(appBar: appBar, body: current);
}
}
更多关于Flutter轮盘选择插件fl_list_wheel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter轮盘选择插件fl_list_wheel的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用fl_list_wheel
插件来实现轮盘选择的示例代码。这个插件允许你创建一个类似于iOS的PickerView的组件,非常适合用于日期选择、选项轮盘等场景。
首先,你需要在你的pubspec.yaml
文件中添加fl_list_wheel
依赖:
dependencies:
flutter:
sdk: flutter
fl_list_wheel: ^0.1.0 # 请检查最新版本号并替换
然后运行flutter pub get
来安装依赖。
接下来是一个简单的示例代码,展示了如何使用fl_list_wheel
创建一个基本的轮盘选择组件:
import 'package:flutter/material.dart';
import 'package:fl_list_wheel/fl_list_wheel.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter List Wheel Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ListWheelPage(),
);
}
}
class ListWheelPage extends StatefulWidget {
@override
_ListWheelPageState createState() => _ListWheelPageState();
}
class _ListWheelPageState extends State<ListWheelPage> {
final List<String> items = List<String>.generate(20, (index) => "Item $index");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter List Wheel Example'),
),
body: Center(
child: ListWheelScrollView(
children: items.map((item) {
return ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
items[index],
style: TextStyle(fontSize: 24),
),
);
},
childCount: items.length,
).build(context, 0); // 这里的0是初始位置索引,实际使用中通常不需要传递
}).toList(),
physics: FixedExtentScrollPhysics(),
itemExtent: 50.0, // 每个item的高度
),
),
);
}
}
注意:上面的代码中有几个需要注意的点:
-
ListWheelScrollView
:这是主要的轮盘组件,它接受一个或多个子组件。在这个例子中,我们使用了ListWheelChildBuilderDelegate
来动态生成子组件。 -
ListWheelChildBuilderDelegate
:这个委托类用于按需构建子组件,避免一次性构建所有子组件带来的性能开销。builder
函数定义了如何构建每个子组件,而childCount
指定了总共有多少个子组件。 -
itemExtent
:定义了每个子组件在轮盘中的垂直或水平占据的空间大小。 -
FixedExtentScrollPhysics
:为轮盘提供了固定的滚动物理效果,使得每次滚动都定位到一个子组件的中心。
错误:上面的代码实际上有一个问题,即ListWheelScrollView
不能直接接受一个ListWheelChildBuilderDelegate
作为子组件。正确的做法是将ListWheelChildBuilderDelegate
传递给ListWheelScrollView
的childDelegate
属性。下面是修正后的代码:
import 'package:flutter/material.dart';
import 'package:fl_list_wheel/fl_list_wheel.dart'; // 注意:实际中可能没有这个包,请使用flutter_list_wheel或其他有效包
// ...(省略main函数和MyApp类)
class _ListWheelPageState extends State<ListWheelPage> {
final List<String> items = List<String>.generate(20, (index) => "Item $index");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter List Wheel Example'),
),
body: Center(
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
items[index],
style: TextStyle(fontSize: 24),
),
);
},
childCount: items.length,
),
itemExtent: 50.0,
physics: FixedExtentScrollPhysics(),
),
),
);
}
}
注意:ListWheelScrollView.useDelegate
可能不是实际API的一部分,这里只是为了说明childDelegate
的使用方式。实际使用中,你应该查看fl_list_wheel
或类似插件的文档,使用正确的API和方法。如果fl_list_wheel
不是你要找的包,请考虑使用flutter_list_wheel_view
或其他类似的包。
希望这个示例能帮助你开始在Flutter项目中使用轮盘选择组件!