SelectionMenu class

create_user: zhengzaihong email:1096877329@qq.com create_date: 2024-02-01 create_time: 14:58 describe: 下拉选择菜单组件 - 高度可定制的下拉框解决方案 Enterprise-level dropdown selection menu component - Highly customizable dropdown solution

功能特性 / Features: • 完全自定义 - 按钮和下拉内容完全由开发者控制 • 智能定位 - 自动检测屏幕边界,防止溢出 • 丰富动画 - 支持自定义过渡动画效果 • 🖱多种触发 - 支持点击、悬停等多种交互方式 • 灵活尺寸 - 支持固定宽度或自适应父组件宽度 • 精确对齐 - 支持左对齐、右对齐、居中对齐 • 状态管理 - 提供Controller进行外部控制 • Material风格 - 支持阴影、圆角、颜色等Material属性

使用示例 / Usage Examples:

// 示例1: 基础下拉菜单
// Example 1: Basic dropdown menu
SelectionMenu(
  popWidth: 200,
  buttonBuilder: (show) {
    return Container(
      height: 40,
      width: 200,
      alignment: Alignment.center,
      padding: const EdgeInsets.only(left: 10, right: 10),
      decoration: BoxDecoration(
        color: Colors.grey.withOpacity(0.2),
        borderRadius: BorderRadius.circular(10),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text("请选择"),
          Icon(show ? Icons.arrow_drop_up : Icons.arrow_drop_down),
        ],
      ),
    );
  },
  selectorBuilder: (context) {
    return Container(
      height: 200,
      margin: const EdgeInsets.only(top: 3),
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(5),
        boxShadow: [
          BoxShadow(
            color: Colors.black12,
            blurRadius: 8,
            offset: Offset(0, 2),
          ),
        ],
      ),
      child: ListView.separated(
        itemCount: 20,
        itemBuilder: (context, index) {
          return GestureDetector(
            onTap: () {
              // 处理选择逻辑
              print("选择了: item $index");
            },
            child: Padding(
              padding: const EdgeInsets.symmetric(vertical: 8),
              child: Text(
                "item $index",
                style: TextStyle(fontSize: 16, color: Colors.black),
              ),
            ),
          );
        },
        separatorBuilder: (BuildContext context, int index) {
          return const Divider();
        },
      ),
    );
  },
)

// 示例2: 使用Controller控制下拉菜单
// Example 2: Using controller to control dropdown
final controller = SelectionMenuController();

SelectionMenu(
  controller: controller,
  popWidth: 200,
  buttonBuilder: (show) => Text("点击展开"),
  selectorBuilder: (context) {
    return Container(
      child: ElevatedButton(
        onPressed: () {
          controller.closePop(); // 关闭下拉菜单
        },
        child: Text("关闭"),
      ),
    );
  },
)

// 示例3: 鼠标悬停触发
// Example 3: Hover trigger
SelectionMenu(
  enableOnHover: true,
  enableClick: false,
  popWidth: 150,
  buttonBuilder: (show) => Text("悬停显示"),
  selectorBuilder: (context) => Container(
    height: 100,
    child: Text("悬停内容"),
  ),
)

// 示例4: 右对齐下拉菜单
// Example 4: Right-aligned dropdown
SelectionMenu(
  alignType: AlignType.right,
  popWidth: 200,
  buttonBuilder: (show) => Text("右对齐"),
  selectorBuilder: (context) => Container(
    height: 150,
    child: Text("下拉内容"),
  ),
)

// 示例5: 自定义Material样式
// Example 5: Custom Material style
SelectionMenu(
  popWidth: 200,
  elevation: 8.0,
  color: Colors.white,
  materialBorderRadius: BorderRadius.circular(12),
  shadowColor: Colors.blue.withOpacity(0.3),
  buttonBuilder: (show) => Text("自定义样式"),
  selectorBuilder: (context) => Container(
    height: 200,
    child: Text("内容"),
  ),
)

⚠️ 注意事项 / Notes: • SelectionMenu不管理数据状态,需要外部自行管理选中状态 • 下拉内容会自动检测屏幕边界,避免溢出 • 使用Controller可以实现外部控制打开/关闭 • buttonBuilder的show参数表示当前下拉菜单是否展开 • 建议在selectorBuilder中处理选择逻辑并更新UI • 支持自定义位置布局,使用layoutSelectPop参数

Inheritance
Available extensions

Constructors

SelectionMenu({required WidgetBuilder selectorBuilder, required DropDownButtonBuilder? buttonBuilder, SelectionMenuController? controller, LayoutSelectPop? layoutSelectPop, DropDownPopCreated? onCreated, DropDownPopShow? onShow, DropDownPopDismiss? onDismiss, bool enableOnHover = false, bool enableClick = true, bool matchParentWidth = true, double popWidth = 0, double hMargin = 0, double vMargin = 0, double popHeight = 200, BorderRadiusGeometry? materialBorderRadius, Color? color = Colors.transparent, ShapeBorder? shape, double elevation = 0.0, Color? shadowColor, String? barrierLabel, Color? barrierColor, bool barrierDismissible = true, Duration transitionDuration = const Duration(milliseconds: 200), AlignType alignType = AlignType.left, GestureTapCallback? onDoubleTap, GestureLongPressCallback? onLongPress, GestureTapDownCallback? onTapDown, GestureTapUpCallback? onTapUp, GestureTapCancelCallback? onTapCancel, ValueChanged<bool>? onHighlightChanged, ValueChanged<bool>? onHover, MouseCursor? mouseCursor, Color? focusColor, Color? hoverColor, Color? highlightColor, WidgetStateProperty<Color?>? overlayColor, Color? splashColor, InteractiveInkFeatureFactory? splashFactory, double? radius, BorderRadius? borderRadius, ShapeBorder? customBorder, bool enableFeedback = true, bool excludeFromSemantics = false, FocusNode? focusNode, bool canRequestFocus = true, ValueChanged<bool>? onFocusChange, bool autofocus = false, Key? key})
const

Properties

alignType AlignType
对齐方式
final
autofocus bool
final
barrierColor Color?
final
barrierDismissible bool
是否允许点击其他区域消失
final
barrierLabel String?
final
borderRadius BorderRadius?
final
buttonBuilder DropDownButtonBuilder?
下拉框构建器
final
canRequestFocus bool
final
color Color?
final
controller SelectionMenuController?
final
customBorder ShapeBorder?
final
elevation double
阴影
final
enableClick bool
是否开启点击
final
enableFeedback bool
final
enableOnHover bool
是否开启鼠标悬浮
final
excludeFromSemantics bool
final
focusColor Color?
final
focusNode FocusNode?
final
hashCode int
The hash code for this object.
no setterinherited
highlightColor Color?
final
hMargin double
水平边距
final
hoverColor Color?
final
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
layoutSelectPop LayoutSelectPop?
自定义下拉框位置
final
matchParentWidth bool
当设置的宽度小于 父组件宽度时, 是否匹配父组件宽度,默认true
final
materialBorderRadius BorderRadiusGeometry?
Material 背景样式
final
mouseCursor MouseCursor?
final
onCreated DropDownPopCreated?
下拉框创建
final
onDismiss DropDownPopDismiss?
下拉框消失
final
onDoubleTap GestureTapCallback?
final
onFocusChange ValueChanged<bool>?
final
onHighlightChanged ValueChanged<bool>?
final
onHover ValueChanged<bool>?
final
onLongPress GestureLongPressCallback?
final
onShow DropDownPopShow?
下拉框显示
final
onTapCancel GestureTapCancelCallback?
final
onTapDown GestureTapDownCallback?
final
onTapUp GestureTapUpCallback?
final
overlayColor WidgetStateProperty<Color?>?
final
popHeight double
窗口高度
final
popWidth double
下拉框宽度 弹窗部分
final
radius double?
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
selectorBuilder WidgetBuilder
下拉框样式构件 弹出部分
final
shadowColor Color?
阴影颜色
final
shape ShapeBorder?
final
splashColor Color?
final
splashFactory InteractiveInkFeatureFactory?
final
transitionDuration Duration
动画时间
final
vMargin double
垂直 边距
final

Methods

blurred({double blur = 5, Color blurColor = Colors.white, BorderRadius? borderRadius, double colorOpacity = 0.5, Widget? overlay, AlignmentGeometry alignment = Alignment.center}) Blur

Available on Widget, provided by the BlurExtension extension

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<SelectionMenu>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
frosted({double blur = 5, Color frostColor = Colors.white, AlignmentGeometry alignment = Alignment.center, double? height, double? width, double frostOpacity = 0.0, BorderRadius? borderRadius, EdgeInsetsGeometry padding = EdgeInsets.zero}) Blur

Available on Widget, provided by the FrostExtension extension

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited