Flutter自定义底部选择器插件custom_bottom_picker的使用
Flutter自定义底部选择器插件 custom_bottom_picker
的使用
custom_bottom_picker
是一个强大的 Flutter 插件,允许开发者轻松实现自定义的底部选择器。该插件不仅支持文本列表的选择,还支持自定义 Widget 列表的选择,并且可以同时显示多个项目。
特性
- 文本选择器
- 自定义 Widget 选择器
- 支持多列选择(文本和 Widget)
- 可定制颜色
示例效果
手机端 | 平板端 |
---|---|
开始使用
添加依赖
在你的 pubspec.yaml
文件中添加以下依赖:
dependencies:
custom_bottom_picker: 1.0.1
然后运行 flutter pub get
来安装依赖。
基本用法
以下是一个简单的示例,展示如何使用 custom_bottom_picker
实现一个国家选择器:
import 'package:custom_bottom_picker/custom_bottom_picker.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(
title: 'Custom Bottom Picker Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: const Color.fromARGB(255, 235, 235, 241),
useMaterial3: false,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int countryIndex = 8;
final List<String> countryData = [
'America',
'Austria',
'Canada',
'Egypt',
'France',
'Greece',
'India',
'Indonesia',
'Japan',
'Malaysia',
'South Africa',
'Spain',
'Viet Nam',
];
void showCountry() async {
final result = await showCustomBottomPicker(
context: context,
options: const CustomBottomPickerOptions(
pickerTitle: 'Country',
),
sections: [
CustomBottomPickerSection.list(
id: 'country',
defaultIndex: countryIndex,
children: countryData,
),
],
);
if (result != null) {
setState(() => countryIndex = result.getById('country')!);
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Custom Bottom Picker Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: showCountry,
child: const Text('Select Country'),
),
),
);
}
}
参数说明
showCustomBottomPicker
方法参数
sections
: 定义要显示在选择器中的每一列的信息。options
: 用于自定义选择器的外观,如背景颜色、文本颜色等。radius
: 设置模态框顶部两边的圆角半径,默认为 24。
CustomBottomPickerSection
id
: 标识选择器中的某一段。children
: 文本列表,用于普通文本显示。itemBuilder
: 如果你想使用自己的 Widget 作为项,则需要指定此函数。
CustomBottomPickerOptions
backgroundColor
: 背景颜色,默认是Theme.of(context).scaffoldBackgroundColor
。foregroundColor
: 前景色,默认是Theme.of(context).cardColor
。textColor
: 文本颜色,默认是Theme.of(context).textTheme.bodyLarge?.color
。activeColor
: 当前选中的日期或按钮的颜色,默认是Theme.of(context).primaryColor
。pickerTitle
: 显示在选择器顶部的标题。
返回值
选择器的返回值类型是 CustomBottomPickerResult
,它继承自 List
,因此也可以像普通列表一样获取值。
CustomBottomPickerResult? result = await showCustomBottomPicker(...);
// 获取第一个项目的值
result![0];
// 使用指定的 ID 获取结果
result!.getById('country');
完整示例 Demo
下面是一个完整的示例 Demo,展示了如何使用 custom_bottom_picker
实现国家选择器、环境和日志级别选择器以及自定义 Widget 选择器。
import 'package:custom_bottom_picker/custom_bottom_picker.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(
title: 'Custom Bottom Picker Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: const Color.fromARGB(255, 235, 235, 241),
useMaterial3: false,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int countryIndex = 8;
List<String> countryData = [
'America',
'Austria',
'Canada',
'Egypt',
'France',
'Greece',
'India',
'Indonesia',
'Japan',
'Malaysia',
'South Africa',
'Spain',
'Viet Nam',
];
int logLevelIndex = 2;
List<String> logLevels = ['Debug', 'Info', 'Warning', 'Error', 'Fatal'];
int envIndex = 1;
List<String> envs = ['Test', 'Develop', 'Staging', 'Production'];
static Widget widgetRow(BuildContext context, String text, Color color) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.stop_rounded, color: color, size: 28),
const SizedBox(width: 8),
Text(
text,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
height: 2,
width: 64,
decoration: BoxDecoration(color: color),
),
Icon(Icons.account_circle_rounded, color: color),
],
);
}
int widgetIndex = 2;
late List<Widget> widgets = [
widgetRow(context, 'Debug', Colors.grey),
widgetRow(context, 'Info', Colors.blue),
widgetRow(context, 'Warning', Colors.orange),
widgetRow(context, 'Error', Colors.red),
widgetRow(context, 'Critical', Colors.purple),
];
void showCountry() async {
final result = await showCustomBottomPicker(
context: context,
options: const CustomBottomPickerOptions(pickerTitle: 'Country'),
sections: [
CustomBottomPickerSection.list(
id: 'country',
defaultIndex: countryIndex,
children: countryData,
),
],
);
if (result != null) {
setState(() => countryIndex = result.getById('country')!);
}
}
void showEnvLog() async {
final result = await showCustomBottomPicker(
context: context,
options: const CustomBottomPickerOptions(pickerTitle: 'Log Level'),
sections: [
CustomBottomPickerSection.list(
id: 'env',
title: 'Environment',
flex: 3,
defaultIndex: envIndex,
children: envs,
),
CustomBottomPickerSection.list(
id: 'level',
title: 'Level',
flex: 2,
defaultIndex: logLevelIndex,
children: logLevels,
),
],
);
if (result != null) {
setState(() {
envIndex = result.getById('env')!;
logLevelIndex = result.getById('level')!;
});
}
}
void showWidgets() async {
final result = await showCustomBottomPicker(
context: context,
options: const CustomBottomPickerOptions(pickerTitle: 'Log Level'),
sections: [
CustomBottomPickerSection.builder(
id: 'widget',
flex: 3,
defaultIndex: envIndex,
itemCount: widgets.length,
itemBuilder: (context, index) {
return widgets[index];
},
),
],
);
if (result != null) {
setState(() {
widgetIndex = result.getById('widget')!;
});
}
}
Widget button(String text, void Function() onTap) {
return Material(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).cardColor,
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: onTap,
child: Container(
height: 48,
width: 240,
alignment: Alignment.center,
child: Text(
text,
style: Theme.of(context).textTheme.bodyMedium,
),
),
),
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
Container(
height: 240,
alignment: Alignment.center,
child: Text(
'Custom Bottom Picker',
style: Theme.of(context)
.textTheme
.headlineSmall
?.copyWith(fontWeight: FontWeight.bold),
),
),
button(
'Country: ${countryData[countryIndex]}',
showCountry,
),
const SizedBox(height: 24),
button(
'LogLevel: ${envs[envIndex]} - ${logLevels[logLevelIndex]}',
showEnvLog,
),
const SizedBox(height: 24),
button(
'Widgets builder',
showWidgets,
),
const SizedBox(height: 24),
],
),
),
);
}
}
更多关于Flutter自定义底部选择器插件custom_bottom_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义底部选择器插件custom_bottom_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用custom_bottom_picker
插件的示例代码。这个插件允许你创建一个自定义的底部选择器,非常适合用于日期选择、时间选择或者任何需要底部弹出选择器的场景。
首先,确保你已经在pubspec.yaml
文件中添加了custom_bottom_picker
依赖:
dependencies:
flutter:
sdk: flutter
custom_bottom_picker: ^最新版本号 # 请替换为实际发布的最新版本号
然后,运行flutter pub get
来获取依赖。
接下来是一个简单的示例代码,展示如何使用custom_bottom_picker
:
import 'package:flutter/material.dart';
import 'package:custom_bottom_picker/custom_bottom_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> {
String _selectedValue = '请选择';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Custom Bottom Picker Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_selectedValue,
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
showPicker(context);
},
child: Text('打开选择器'),
),
],
),
),
);
}
void showPicker(BuildContext context) {
List<String> items = ['选项1', '选项2', '选项3', '选项4', '选项5'];
showCustomBottomPicker(
context: context,
builder: (context) {
return CustomBottomPicker(
itemCount: items.length,
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
child: Text(items[index]),
);
},
onConfirm: (index) {
setState(() {
_selectedValue = items[index];
});
Navigator.of(context).pop();
},
);
},
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮和一个文本显示区域。当用户点击按钮时,会弹出一个底部选择器。选择器的选项是预定义的字符串列表。当用户选择一个选项并点击确认时,选择的选项会显示在文本区域中。
关键部分是showPicker
函数,它使用showCustomBottomPicker
方法来显示选择器。CustomBottomPicker
小部件通过itemBuilder
回调来构建每个选项的UI,并通过onConfirm
回调来处理用户的选择。
这个示例提供了一个基本的框架,你可以根据自己的需求进一步自定义和扩展它,比如添加更多的样式、处理更复杂的数据等。