自定义可跟随父Widget弹出显示的弹窗效果。支持自定义事件,默认 转发、收藏、删除。有需要的小伙伴可以直接拿去使用。
- 实现要点
- 参考PopMenu实现弹出透明页面,借鉴了https://blog.csdn.net/email_jade/article/details/87922051这位老哥的思想。
class CustomRoute extends PopupRoute {
Widget child;
CustomRoute({@required this.child});
@override
Color get barrierColor => null;
@override
bool get barrierDismissible => true;
@override
String get barrierLabel => null;
@override
Widget buildPage(BuildContext context, Animation animation,
Animation secondaryAnimation) {
return child;
}
@override
Duration get transitionDuration => Duration(milliseconds: 200);
}
- 参考flutter 的
toolTip
实现弹窗的位置绑定
///参考tooltip的控件绑定
class _PositionDelegate extends SingleChildLayoutDelegate {
_PositionDelegate({
@required this.target,
@required this.verticalOffset,
@required this.preferBelow,
}) : assert(target != null),
assert(verticalOffset != null),
assert(preferBelow != null);
final Offset target;
final double verticalOffset;
final bool preferBelow;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) =>
constraints.loosen();
@override
Offset getPositionForChild(Size size, Size childSize) {
return positionDependentBox(
size: size,
childSize: childSize,
target: target,
verticalOffset: verticalOffset,
preferBelow: preferBelow,
);
}
@override
bool shouldRelayout(_PositionDelegate oldDelegate) {
return target != oldDelegate.target ||
verticalOffset != oldDelegate.verticalOffset ||
preferBelow != oldDelegate.preferBelow;
}
}
- 弹窗布局文件(这个完全可以根据自生需求修改)
CustomSingleChildLayoutl
///弹窗 widget
Widget _buildChild(BuildContext context, double verOffset, bool isPrefer,
List items) {
final RenderBox box = context.findRenderObject();
final Offset target = box.localToGlobal(box.size.topCenter(Offset.zero));
/*
*
*const CustomSingleChildLayout({
Key key,
@required this.delegate,//控制子项布局的委托。
Widget child,
}) : assert(delegate != null),
super(key: key, child: child);*/
return CustomSingleChildLayout(
//位置绑定
delegate: _PositionDelegate(
target: target,
verticalOffset: verOffset ?? 0.0,
preferBelow: isPrefer ?? false,
),
child: GestureDetector(
child: Container(
width: (items == null || items.isEmpty)
? 171.0
: ((items.length) / 2) * 57.0,
height: 45.0,
child: Column(
children: [
Container(
height: 36.0,
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Color(0xe6060606),
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: items ??
[
GestureDetector(
child: Text(
'转发',
style: TextStyle(color: Colors.white),
),
onTap: onDefaultForward,
onTapCancel: () => Navigator.of(context).pop(),
),
Container(
width: 0.5,
color: Colors.white,
),
GestureDetector(
onTap: onDefaultCollection,
child:
Text('收藏', style: TextStyle(color: Colors.white)),
),
Container(
width: 0.5,
color: Colors.white,
),
GestureDetector(
onTap: onDefaultDelete,
child:
Text('删除', style: TextStyle(color: Colors.white)),
)
],
),
),
Image.asset('assets/images/icon_black_arrow_down.png')
],
),
),
),
);
}
}
- CustomRoute的使用请参考我的 PopupRoute文章
完整代码已上传我的 github