Flutter下拉菜单插件flex_dropdown的使用
Flutter下拉菜单插件flex_dropdown的使用
Flex DropDown | Custom DropDown
通过Flex DropDown插件,你可以轻松创建优雅且可定制的下拉菜单。这个Flutter插件允许你方便地实现带有自定义样式、动画和数据源的下拉菜单,以满足你的应用需求。
开始使用
如果你对这个包的开发背景故事感兴趣,可以阅读我们在Medium上的文章:Creating Custom Dropdowns with OverlayPortal in Flutter。
要开始使用Flex DropDown插件,请确保你已经安装了Flutter并且对Flutter插件的基本操作有所了解。你可以按照以下步骤将插件集成到你的项目中:
- 在
pubspec.yaml
文件中添加如下依赖:dependencies: flex_dropdown: ^0.1.0
- 运行以下命令获取插件:
flutter pub get
- 在Dart代码中导入插件:
import 'package:flex_dropdown/flex_dropdown.dart';
在线演示
你可以通过以下链接查看Flex DropDown的交互式在线示例:Flex DropDown Online Example。
使用方法
下面是一个简单的例子,展示了如何使用Flex DropDown插件:
import 'package:flex_dropdown/flex_dropdown.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final OverlayPortalController _controller = OverlayPortalController();
MenuPosition position = MenuPosition.bottomStart;
bool dismissOnTapOutside = true;
bool useButtonSize = true;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.onInverseSurface,
appBar: AppBar(
title: const Text('Flex Drop Down'),
),
body: Column(
children: [
const SizedBox(height: 150),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 64.0),
child: RawFlexDropDown(
controller: _controller,
menuPosition: position,
dismissOnTapOutside: dismissOnTapOutside,
buttonBuilder: (context, onTap) {
return ButtonWidget(
width: 400,
onTap: onTap,
);
},
menuBuilder: (context, width) {
return Padding(
padding: const EdgeInsets.only(top: 4),
child: MenuWidget(
width: useButtonSize ? width : 300,
onItemTap: () {
_controller.hide();
},
),
);
},
),
),
),
const SizedBox(height: 250),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Dismiss on tap outside'),
const SizedBox(width: 8),
Switch(
value: dismissOnTapOutside,
onChanged: (value) {
setState(() {
dismissOnTapOutside = value;
});
},
),
const SizedBox(width: 32),
const Text('Use button size'),
const SizedBox(width: 8),
Switch(
value: useButtonSize,
onChanged: (value) {
setState(() {
useButtonSize = value;
});
},
),
],
),
const SizedBox(height: 32),
Wrap(
children: [
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.bottomStart;
});
},
child: const Text("Bottom Left"),
),
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.bottomEnd;
});
},
child: const Text("Bottom Right"),
),
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.bottomCenter;
});
},
child: const Text("Bottom Center"),
),
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.topStart;
});
},
child: const Text("Top Left"),
),
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.topEnd;
});
},
child: const Text("Top Right"),
),
ElevatedButton(
onPressed: () {
setState(() {
position = MenuPosition.topCenter;
});
},
child: const Text("Top Center"),
),
],
),
],
),
);
}
}
class ButtonWidget extends StatelessWidget {
const ButtonWidget({
super.key,
this.height = 48,
this.width,
this.onTap,
this.child,
});
final double? height;
final double? width;
final VoidCallback? onTap;
final Widget? child;
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: width,
child: Material(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: const BorderSide(color: Colors.black12),
),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(10),
child: const Center(child: Text('Button')),
),
),
);
}
}
class MenuWidget extends StatelessWidget {
const MenuWidget({
super.key,
this.width,
required this.onItemTap,
});
final double? width;
final VoidCallback onItemTap;
@override
Widget build(BuildContext context) {
return Container(
width: width,
padding: const EdgeInsets.all(8),
decoration: ShapeDecoration(
color: Theme.of(context).colorScheme.primaryContainer,
shape: RoundedRectangleBorder(
side: const BorderSide(
width: 1.5,
color: Colors.black26,
),
borderRadius: BorderRadius.circular(12),
),
shadows: const [
BoxShadow(
color: Color(0x11000000),
blurRadius: 32,
offset: Offset(0, 20),
spreadRadius: -8,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: _FakeItemHolder(
text: 'Item 1',
onTap: onItemTap,
),
),
const SizedBox(width: 8),
Expanded(
child: _FakeItemHolder(
text: 'Item 2',
onTap: onItemTap,
),
),
],
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: _FakeItemHolder(
text: 'Item 3',
onTap: onItemTap,
),
),
const SizedBox(width: 8),
Expanded(
child: _FakeItemHolder(
text: 'Item 4',
onTap: onItemTap,
),
),
],
),
],
),
);
}
}
class _FakeItemHolder extends StatelessWidget {
const _FakeItemHolder({
required this.text,
required this.onTap,
});
final String text;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SizedBox(
height: 80,
child: Material(
color: theme.colorScheme.onPrimary,
shape: RoundedRectangleBorder(
side: BorderSide(
width: 1,
color: theme.colorScheme.onSurfaceVariant,
),
borderRadius: BorderRadius.circular(12),
),
child: InkWell(
borderRadius: BorderRadius.circular(12),
onTap: onTap,
child: Center(child: Text(text)),
),
),
);
}
}
额外信息
如果你遇到任何问题、有建议或想要为这个包做贡献,欢迎在GitHub仓库中提交问题或Pull Request。
我们重视社区反馈,并致力于及时回应您可能有的任何疑问或担忧。
更多关于Flutter下拉菜单插件flex_dropdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter下拉菜单插件flex_dropdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用flex_dropdown
插件来创建下拉菜单的示例代码。flex_dropdown
是一个增强版的下拉菜单插件,它提供了更多的自定义选项和更好的用户体验。
首先,确保你的pubspec.yaml
文件中已经添加了flex_dropdown
依赖:
dependencies:
flutter:
sdk: flutter
flex_dropdown: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个使用flex_dropdown
的完整示例代码:
import 'package:flutter/material.dart';
import 'package:flex_dropdown/flex_dropdown.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flex Dropdown Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String? selectedValue;
final List<String> dropdownValues = ['Option 1', 'Option 2', 'Option 3'];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flex Dropdown Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FlexDropdown(
containerDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.shade300),
),
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
buttonDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.blue.shade300,
),
buttonTextStyle: TextStyle(color: Colors.white),
dropdownTextStyle: TextStyle(color: Colors.black),
value: selectedValue,
hint: Text('Select an option'),
onChanged: (value) {
setState(() {
selectedValue = value;
});
},
items: dropdownValues.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 导入
flex_dropdown
包。 - 创建一个包含下拉菜单的主页面。
- 使用
FlexDropdown
小部件来创建下拉菜单。 - 设置下拉菜单的容器装饰、下拉菜单项的装饰、按钮装饰、按钮文本样式和下拉菜单项的文本样式。
- 定义下拉菜单的值和提示文本。
- 实现
onChanged
回调函数,当用户选择一个选项时更新selectedValue
状态。
这个示例展示了flex_dropdown
的基本用法,你可以根据需要进一步自定义和扩展它。