问题背景
客户端日常开发和学习过程,下拉菜单是一个很常见的组件,本文主要介绍flutter中实现下拉菜单组件的一个方案,基于PopupMenuButton来进行实现。
问题分析
PopupMenuButton PopupMenuButton 是一个非常常见的弹出菜单栏。 属性介绍:
问题解决
话不多说,直接上代码 (1)新建MenuItem.dart通用菜单项类,代码如下:
/// author baorant
/// 通用菜单项
class MenuItem {
// 显示的文本
String label;
// 选中的值
dynamic value;
// 是否选中
bool checked;
MenuItem({this.label = '', this.value, this.checked = false});
}
(2)实现SelectWidget.dart下拉菜单项组件,代码如下:
import 'package:flutter/material.dart';
import 'MenuItem.dart';
/// @author baorant
/// @创建时间:2024/4/11
/// 下拉菜单按钮组件
class SelectWidget extends StatefulWidget {
// 显示的菜单项
final List<MenuItem> items;
// 当前选中的值
final dynamic value;
// 选择框前的标题
final String? title;
// 提示语
final String tooltip;
// 选中数据的回调事件
final ValueChanged<dynamic>? valueChanged;
const SelectWidget(
{Key? key,
this.items = const [],
this.value,
this.valueChanged,
this.title,
this.tooltip = "点击选择"})
: super(key: key);
@override
State<SelectWidget> createState() => _SelectWidgetState();
}
class _SelectWidgetState extends State<SelectWidget> {
String label = '请选择';
// 是否展开下拉按钮
bool isExpand = false;
// 当前的值
dynamic currentValue;
@override
void initState() {
currentValue = widget.value;
super.initState();
}
/// 根据当前的value处理当前文本显示
void initTitle() {
if (currentValue != null) {
// 有值查值
for (MenuItem item in widget.items) {
if (item.value == currentValue) {
label = item.label;
return;
}
}
}
// 没值默认取第一个
if (widget.items.isNotEmpty) {
label = widget.items[0].label;
}
}
@override
Widget build(BuildContext context) {
initTitle();
return Wrap(
children: [
if (widget.title != null)
Text(widget.title!, style: TextStyle(fontSize: 18)),
PopupMenuButton<String>(
// initialValue: currentValue,
tooltip: widget.tooltip,
offset: Offset(25, 30),
enableFeedback: true,
child: Listener(
// 使用listener事件能够继续传递
onPointerDown: (event) {
setState(() {
isExpand = !isExpand;
});
},
child: Wrap(
children: [
Text(
label,
style: TextStyle(fontSize: 18),
),
isExpand
? const Icon(Icons.arrow_drop_up)
: const Icon(Icons.arrow_drop_down)
],
),
),
onSelected: (value) {
widget.valueChanged?.call(value);
setState(() {
currentValue = value;
isExpand = !isExpand;
});
},
onCanceled: () {
// 取消展开
setState(() {
isExpand = false;
});
},
itemBuilder: (context) {
return widget.items
.map(
(item) => item.value == currentValue
? PopupMenuItem<String>(
value: item.value,
child: Text(
item.label,
style: TextStyle(
color: Theme.of(context).primaryColor),
),
)
: PopupMenuItem<String>(
value: item.value,
child: Text(item.label),
),
).toList();
},
)
],
);
}
}
(3)测试代码如下:
import 'package:flutter/material.dart';
import '../../../components/select_menu/MenuItem.dart';
import '../../../components/select_menu/SelectWidget.dart';
import '../../../utils/custom_appbar.dart';
class Test extends StatefulWidget {
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
String value = "1";
/// 下拉选择值改变
selectChange(value) {
print("值改变了:$value");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: customAppbar(
title: "下拉菜单演示",
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SelectWidget(
items: [
MenuItem(label: "张飞", value: '1'),
MenuItem(label: "关羽", value: '2'),
MenuItem(label: "刘备", value: '3'),
MenuItem(label: "亚瑟", value: '4'),
MenuItem(label: "妲己", value: '5'),
MenuItem(label: "兰陵王", value: '6'),
],
value: value,
valueChanged: selectChange,
),
],
),
);
}
}
(4)运行结果如下: 文章来源:https://www.toymoban.com/news/detail-724928.html
问题总结
本文主要介绍flutter中实现下拉菜单组件的一个方案,基于PopupMenuButton来进行实现,有兴趣的同学可以进一步深入研究。文章来源地址https://www.toymoban.com/news/detail-724928.html
到了这里,关于flutter实现下拉菜单组件——基于PopupMenuButton的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!