关于Flutter遮罩箭头菜单

发布一下 0 0


关于Flutter遮罩箭头菜单

示例图


关于Flutter遮罩箭头菜单

代码展示:

menu.dart文件:

import 'package:flutter/material.dart';import 'arrow_list.dart';import 'fade_popup.dart';import 'mask.dart';class FCArrowMenuScreen extends StatefulWidget {  static const routeName = '/arrow_menu';  @override  _FCArrowMenuScreenState createState() => _FCArrowMenuScreenState();}class _FCArrowMenuScreenState extends State<FCArrowMenuScreen> {  GlobalKey<_FCArrowMenuScreenState> _globalKey = GlobalKey();  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Top Arrow Menu')      ),      body: Stack(        children: [          Positioned( // Positioned只能配合 Stack 使用            left: 150,            top: 150,            child: IconButton(              key: _globalKey,              icon: Icon(Icons.add_circle, size: 35, color: Colors.yellow[800]),               onPressed: () {                // 获取 IconButton 在屏幕上的坐标                  // 1.先获取此组件, 利用组件绑定的key                  // 2.组件自身的左上角 转屏幕坐标(零点)                RenderBox box = _globalKey.currentContext.findRenderObject();                Offset boxZeroOffset = box.localToGlobal(Offset.zero);                Size boxSize = box.size;                double menuX = boxZeroOffset.dx - FCArrowMenu.menuWidth * 0.5 + box.size.width * 0.5;                double menuY = boxZeroOffset.dy + boxSize.height;                Navigator.of(context).push(                    /** 自定义动效路由*/                  FCFadePopupRoute(child: FCMask(child: FCArrowMenu(), left: menuX, top: menuY))                  /** 可使用 PageRouteBuilder路由: 系统自带动效路由;                       PageRouteBuilder继承PopupRoute*/                  // PageRouteBuilder(                  //   opaque: false,                  //   barrierDismissible: true,                  //   maintainState: true,                  //   transitionDuration: Duration(milliseconds: 250),                  //   pageBuilder: (context, animation, secondaryAnimation) {                  //     return FadeTransition(                  //       opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn)),                  //       child: FCMask(child: FCArrowMenu(), left: menuX, top: menuY),                  //     );                  // })                );              }            ),          )        ]      ),    );  }}

fade_popup.dart文件:自定义动效

import 'package:flutter/material.dart';class FCFadePopupRoute extends PopupRoute {  final Widget child;  FCFadePopupRoute({@required this.child});  @override  Color get barrierColor => null;  @override  String get barrierLabel => null;  @override  bool get barrierDismissible => true;  @override  bool get maintainState => true;  @override  Duration get transitionDuration => Duration(milliseconds: 250);  @override  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {    return FadeTransition(      opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animation, curve: Curves.easeIn)),      child: child,    );  }}

mask.dart文件:

import 'package:flutter/material.dart';class FCMask extends StatelessWidget {  final Widget child;  final double left;  final double top;  FCMask({    @required this.child,    this.left,     this.top  });  @override  Widget build(BuildContext context) {    return Scaffold( // 这里也可以使用 Material(color: Colors.transparent, child: xxx)      backgroundColor: Colors.transparent,      body: GestureDetector(        onTap: ()=>Navigator.of(context).pop(),        child: Stack(          children: [            Container( // 底部全屏黑色透明背景              width: double.infinity,              height: double.infinity,              color: Colors.black.withOpacity(0.55)            ),            Positioned(              top: top,              left: left,              child: child            )          ],        )      ),    );  }}

arrow_list.dart文件:

import 'package:flutter/material.dart';import 'dart:ui' as ui;// cell显示内容数据模型class MenuItem {  final Widget leading;  final String title;  MenuItem({    this.leading,    this.title  });}// items数据源List<MenuItem> items = [  MenuItem(leading: Icon(Icons.warning_amber_rounded, color: Colors.white, size: 28), title: "异常提示"),  MenuItem(leading: Icon(Icons.update_rounded, color: Colors.white, size: 28), title: "更新信息"),  MenuItem(leading: Icon(Icons.message_rounded, color: Colors.white, size: 28), title: "回复信息")];class FCArrowMenu extends StatelessWidget {  static double menuWidth = MediaQueryData.fromWindow(ui.window).size.width *0.35;    @override  Widget build(BuildContext context) {    return Container(      width: menuWidth,      child: Column(        children: [          // Image.asset('assets/images/img_up_arrow.png', width: 25.0, height: 13.4),          FCTrigon(), // 自定义绘制箭头          Container(            constraints: BoxConstraints(maxHeight: 45.0*5), // 设置最大容器高度            padding: EdgeInsets.only(left: 8, right: 8),            decoration: BoxDecoration(              color: Colors.black.withOpacity(0.55),              borderRadius: BorderRadius.circular(5)            ),            child: ListView.builder(              shrinkWrap: true,              padding: EdgeInsets.zero,              itemCount: items.length,              itemBuilder: (context, index) {                Widget leading = items[index].leading;                String title = items[index].title;                return GestureDetector(                  child: Container(                    padding: EdgeInsets.only(top: 8, bottom: 8),                    child: Row(                      mainAxisAlignment: MainAxisAlignment.start,                      crossAxisAlignment: CrossAxisAlignment.center,                      children: [                        leading,                        SizedBox(width: 8),                        Expanded(                          child: Text(title, style: TextStyle(                            fontSize: 17,                            color: Colors.white,                            fontWeight: FontWeight.bold                          )),                        )                      ],                    ),                  ),                  onTap: () {                    print("$title");                  },                );              },            ),          )        ],      ),    );  }}/* 绘制三角形 */ class FCTrigon extends StatelessWidget {  @override  Widget build(BuildContext context) {    return ClipPath(      clipper: FCTrigonPath(),      child: Container(        width: 25.0,        height: 13.4,        color: Colors.black.withOpacity(0.55),      ),    );  }}class FCTrigonPath extends CustomClipper<Path> {    @override  Path getClip(Size size) {    Path path = Path();    path.moveTo(0, size.height);    path.lineTo(size.width * 0.5, 0);    path.lineTo(size.width, size.height);    path.close();    return path;  }    @override  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {    return true;  }}



版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/202024.html