概述
import 'dart:math'; import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:wrapper/wrapper.dart'; class BtnPopupWidget extends StatefulWidget { final double spineHeight; final bool formEnd; final double width; final double height; final double angle; final double right; final double btnHeight; final double btnWidth; final Widget content; BtnPopupWidget( { Key? key, required this.width, required this.height, required this.btnHeight, required this.btnWidth, required this.content, this.spineHeight=12, this.angle=80, this.right=0, this.formEnd=false }) : super(key: key); @override State<BtnPopupWidget> createState() => _BtnPopupWidgetState(); } class _BtnPopupWidgetState extends State<BtnPopupWidget> with SingleTickerProviderStateMixin{ final LayerLink _layerLink = LayerLink(); bool show = false; OverlayEntry? _overlayEntry; AnimationController? controller;//动画控制器 // CurvedAnimation? curved;//曲线动画,动画插值, late final Animation<Offset> _offset; @override void initState() { // TODO: implement initState super.initState(); controller = new AnimationController( vsync: this, duration: const Duration(seconds: 2)); //设置动画 _offset= Tween<Offset>( begin:const Offset(0, -0.5) , end: Offset.zero, ).animate(CurvedAnimation( parent: controller!, curve: Curves.bounceOut, ) ..addListener((){ setState(() { }); }) ..addStatusListener((status) { if(status==AnimationStatus.reverse){ status=AnimationStatus.completed; } }) ); } @override Widget build(BuildContext context) { return CompositedTransformTarget( link: _layerLink, child: GestureDetector( onTap: () { if (show) { show = false; _overlayEntry!.remove(); controller!.reverse(); } else { _overlayEntry = EmojiPanel(); show = true; Overlay.of(context)?.insert(_overlayEntry!); controller!.forward(); } }, child: Container( child: Text("按钮"), ), ), ); } OverlayEntry EmojiPanel() { double _spineHeight =widget.spineHeight; // bool _formEnd = true; double _width =widget.width; double _height =widget.height; double _angle = widget.angle; double right =widget.right; double btnHeight = widget.btnWidth; double btnWidth=widget.btnWidth; ///尖端路径构造器 Path _spinePathBuilder(Canvas canvas, SpineType spineType, Rect range) { ///从尾部偏移计算相关坐标 var lineHeight = _height - _spineHeight; var angleRad = pi / 180 * _angle; var sideLength = _spineHeight * tan(angleRad / 2); var offset = right + btnWidth/2; var startX = _width - offset - sideLength; var stratY = lineHeight; var controlPointX = _width - offset; var controlPointY = _height + btnHeight / 3; var endX = startX + sideLength * 2; var endY = lineHeight; //绘制双曲线 return Path() ..moveTo(startX, stratY) ..conicTo(controlPointX, controlPointY, endX, endY, 1.5); } return OverlayEntry(builder: (context) { ///排除父级对子级的约束 return UnconstrainedBox( child: CompositedTransformFollower( ///主体的位置 followerAnchor: Alignment.bottomRight, ///浮窗的位置 targetAnchor: Alignment.topRight, offset: Offset(0, -5), link: _layerLink, //显示动画设置 child: SlideTransition( position: _offset, child: Container( width: _width, height: _height, child: Wrapper( padding: EdgeInsets.zero, ///箭头 spinePathBuilder: _spinePathBuilder, ///箭头高度 spineHeight: _spineHeight, ///背景色 color: Colors.white, ///箭头位置 spineType: SpineType.bottom, ///影深 elevation: 10, ///从尾部偏移 // formEnd: _formEnd, ///偏移量 // offset: 150, ///阴影颜色 shadowColor: Colors.black.withAlpha(88), ///圆角半径 radius: 10, ///针尖夹角 // angle: _angle, ///内容 child: widget.content ), ), ), ), ); }); } @override void dispose() { // TODO: implement dispose super.dispose(); _overlayEntry!.remove(); controller!.dispose(); } }
最后
以上就是背后丝袜为你收集整理的flutter中点击按钮滑动弹出弹框、变更弹框箭头的全部内容,希望文章能够帮你解决flutter中点击按钮滑动弹出弹框、变更弹框箭头所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复