• Flutter全局menu弹框


    全屏幕menu弹框,可以设置位置,居中,居左,居右,居顶,居底部。默认右上角位置
    
    
    import 'dart:math' as math;
    import 'dart:ui' as ui show window;
    import 'package:flutter/material.dart';
    import 'package:simple_animations/simple_animations.dart';
    import 'package:supercharged/supercharged.dart';
    
    class FSMenuPopModel {
      String? title;
      String? id;
      String? icon;
      bool selected; // 是否选中
    
      FSMenuPopModel({
        this.title,
        this.id,
        this.selected = false,
        this.icon,
      });
    }
    
    enum FSMenuLayoutType {
      left, //从左开始
      xCenter,
      right, //从右开始
      top, //从上开始
      yCenter,
      bottom, //从下开始
    }
    
    /**
     * example:
        FSMenuPopModel currentModel = FSMenuPopModel();
        showPop() {
        List list = [];
    
        for (int i = 0; i < 5; i++){
        FSMenuPopModel model1 = FSMenuPopModel();
        model1.title = '排序'+i.toString();
        model1.id = (100 + i).toString();
        model1.icon = R.assetsImgCommonQiehuan;
        model1.selected = model1.id == currentModel.id;
        list.add(model1);
        }
    
        DialogUtil.showMaskView(
        FSMenuPopView(
        itemList: list,
        xLayoutType: FSMenuLayoutType.right,
        // yLayoutType: NavMenuLayoutType.yCenter,
        activeBackground: StyleColor.theme_light_gray,
        yMargin: 10 + ScreenUtil.getAppBarHeight,
        onTap: (FSMenuPopModel model) async {
        currentModel = model;
        NavigatorUtil.pop();
        },
        ),
        backgroundColor: Colors.black.withAlpha(0)
        );
        }
     * */
    
    /// 选择menu
    class FSMenuPopView extends StatefulWidget {
      final ValueSetter? onTap; //点击回调方法
      final List? itemList;
      final Color? menuBackground;
      final Color? normalBackground;
      final Color? activeBackground;
      final double? borderRadius;
      final double? horizontalSpace; //左右边距
      final double? itemVerticalSpace; //上下边距
      final double? imgWidth;
      TextStyle? activeTextStyle;
      TextStyle? normalTextStyle;
    
      ///定位,默认右上角弹出
      final FSMenuLayoutType? yLayoutType; //y定位类型,默认从顶部
      final FSMenuLayoutType? xLayoutType; //x定位类型,默认从右侧
      final double? xMargin; //距离左右定位的边距,需结合xLayoutType枚举使用
      final double? yMargin; //距离上下定位的边距,需结合yLayoutType枚举使用
    
      FSMenuPopView({
        @required this.onTap,
        @required this.itemList,
        this.xMargin,
        this.yMargin,
        this.xLayoutType,
        this.yLayoutType,
        this.menuBackground = Colors.white,
        this.normalBackground = Colors.white,
        this.activeBackground = Colors.white,
        this.activeTextStyle,
        this.normalTextStyle,
        this.borderRadius = 5,
        this.imgWidth = 15,
        this.horizontalSpace,
        this.itemVerticalSpace,
      });
    
      @override
      _FSMenuViewState createState() => _FSMenuViewState();
    }
    
    class _FSMenuViewState extends State {
      // 获取状态栏高度
      static final MediaQueryData _mediaQueryData = MediaQueryData.fromWindow(ui.window);
    
      static double get _getStatusBarHeight => _mediaQueryData.padding.top;
    
      //内容距离视图左右默认边距
      double get _defaultSpaceHorizontal => 20;
    
      //内容距离视图上下默认边距
      double get _defaultSpaceVertical => 10;
    
      TextStyle get _activeDefaultTextStyle => TextStyle(color: Colors.black, fontSize: 16);
    
      TextStyle get _normalDefaultTextStyle => TextStyle(color: Color(0xFF595961), fontSize: 16);
    
      //y布局
      double get _defaultYMargin => _getStatusBarHeight;
    
      FSMenuLayoutType get _defaultLayoutTypeY => FSMenuLayoutType.top;
    
      //x布局
      double get _defaultXMargin => 20;
    
      FSMenuLayoutType get _defaultLayoutTypeX => FSMenuLayoutType.right;
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Container(
            decoration: BoxDecoration(
              color: Colors.black.withAlpha(0),
            ),
            child: PlayAnimation(
              tween: 0.0.tweenTo(1.0),
              duration: 300.milliseconds,
              curve: Curves.easeOut,
              builder: (context, child, value) {
                return Transform.scale(
                  scale: value,
                  child: Column(
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      //顶部占位视图
                      (widget.yLayoutType ?? _defaultLayoutTypeY) == FSMenuLayoutType.top
                          ? Container(height: widget.yMargin ?? _defaultYMargin)
                          : Expanded(
                              child: Container(
                              color: Colors.black.withAlpha(0),
                            )),
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          //左侧占位视图
                          (widget.xLayoutType ?? _defaultLayoutTypeX) == FSMenuLayoutType.left
                              ? Container(width: widget.xMargin ?? _defaultXMargin)
                              : Expanded(child: Container()),
                          //内容
                          _contentWidget,
                          //右侧占位视图
                          (widget.xLayoutType ?? _defaultLayoutTypeX) == FSMenuLayoutType.right
                              ? Container(width: widget.xMargin ?? _defaultXMargin)
                              : Expanded(child: Container()),
                        ],
                      ),
                      //底部占位视图
                      (widget.yLayoutType ?? _defaultLayoutTypeY) == FSMenuLayoutType.bottom
                          ? Container(height: widget.yMargin ?? _defaultYMargin)
                          : Expanded(child: Container()),
                    ],
                  ),
                );
              },
            ),
          ),
        );
      }
    
      /// 界面
      Widget get _contentWidget {
        return Container(
          clipBehavior: Clip.antiAlias,
          decoration: new BoxDecoration(
            color: widget.menuBackground ?? Colors.white,
            borderRadius: BorderRadius.all(
              Radius.circular(widget.borderRadius ?? 0),
            ),
            boxShadow: [
              BoxShadow(
                offset: Offset(4.0, 4.0),
                blurRadius: 10,
                color: Color(0xFFF2F2F6),
              )
            ],
          ),
          child: Column(
            children: (widget.itemList ?? []).map((item) {
              return GestureDetector(
                onTap: () {
                  if (widget.onTap != null) widget.onTap!(item);
                },
                child: Container(
                  decoration: BoxDecoration(
                    border: Border(
                      bottom: item == (widget.itemList ?? []).last
                          ? BorderSide.none
                          : BorderSide(
                              width: 1,
                              color: Color(0xFFEFEFEF),
                            ),
                    ),
                  ),
                  child: Container(
                    padding: EdgeInsets.symmetric(
                      vertical: (widget.itemVerticalSpace ?? _defaultSpaceVertical),
                      horizontal: (widget.horizontalSpace ?? _defaultSpaceHorizontal),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Offstage(
                          offstage: item.icon == null || item.icon!.isEmpty,
                          child: Padding(
                            padding: const EdgeInsets.only(right: 8.0),
                            child: Image.asset(
                              item.icon ?? '',
                              width: widget.imgWidth,
                              height: widget.imgWidth,
                            ),
                          ),
                        ),
                        Text(
                          item.title ?? '',
                          textAlign: TextAlign.center,
                          style: item.selected == true ? (widget.activeTextStyle ?? _activeDefaultTextStyle) : (widget.normalTextStyle ?? _normalDefaultTextStyle),
                        ),
                      ],
                    ),
                    decoration: BoxDecoration(
                      color: item.selected == true ? widget.activeBackground : widget.normalBackground,
                    ),
                  ),
                ),
              );
            }).toList(),
          ),
        );
      }
    
    }
    
  • 相关阅读:
    Fabric区块链浏览器搭建
    0720~放假自习
    【优化选址】基于matlab遗传算法求解物流配送中心选址【含Matlab源码 1917期】
    C++:stl_List的介绍与模拟实现
    TypeScritpt中的namespace
    【Python基础之函数:多层语法糖、装饰器和装饰器修复技术及递归函数】
    JS-项目实战-点击水果名修改特定水果库存记录
    springboot实现自定义注解限流
    steam搬砖项目,小白也能月入过万的副业项目
    HybridCLR 示例项目简析
  • 原文地址:https://blog.csdn.net/ModalYin/article/details/126557415