Commit ded174bb authored by skeyboy's avatar skeyboy

文本消息长按菜单

parent c69c35c4
......@@ -115,6 +115,7 @@ class _CustomPopupMenuState extends State<CustomPopupMenu> {
),
child: CustomMultiChildLayout(
delegate: _MenuLayoutDelegate(
itemSize: _childBox?.size ?? Size.zero,
tapedPoint: _controller?.localPosition ?? Offset.zero,
anchorSize: _childBox!.size,
anchorOffset: _childBox!.localToGlobal(
......@@ -289,9 +290,14 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
required this.anchorOffset,
required this.verticalMargin,
required this.tapedPoint,
required this.itemSize,
this.position,
});
// 消息列表的的大小
final Size itemSize;
/// 消息列表点击的位置
final Offset tapedPoint;
final Size anchorSize;
final Offset anchorOffset;
......@@ -328,7 +334,8 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
BoxConstraints.loose(size),
);
}
print("文本内容大小 $size $contentSize $anchorOffset 点击位置$tapedPoint");
print(
"文本内容大小 $size $contentSize$itemSize $anchorOffset 点击位置$tapedPoint");
bool isTop = false;
if (position == null) {
// auto calculate position
......@@ -336,6 +343,13 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
} else {
isTop = position == PreferredPosition.top;
}
// 长消息上滑后底部有充分的空间才可以
if (itemSize.height + anchorOffset.dy - size.height <
-(contentSize.height * 1.2 + arrowOffset.dy + verticalMargin) &&
anchorOffset.dy < 0) {
isTop = false;
}
if (anchorCenterX - contentSize.width / 2 < 0) {
menuPosition = isTop ? _MenuPosition.topLeft : _MenuPosition.bottomLeft;
} else if (anchorCenterX + contentSize.width / 2 > size.width) {
......@@ -373,19 +387,31 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
);
break;
case _MenuPosition.topCenter:
double contentOffsetY = 0.0;
double arrowOffsetY = 0.0;
if (anchorTopY <= contentSize.height) {
// 使用 点击位置
contentOffsetY =
tapedPoint.dy - contentSize.height + anchorTopY - verticalMargin;
arrowOffsetY = tapedPoint.dy + anchorTopY - verticalMargin;
} else {
arrowOffsetY = math.max(
anchorTopY - verticalMargin - arrowSize.height,
contentSize.height * 2);
contentOffsetY = math.max(
anchorTopY -
verticalMargin -
arrowSize.height -
contentSize.height,
contentSize.height);
}
arrowOffset = Offset(
anchorCenterX - arrowSize.width / 2,
math.max(anchorTopY - verticalMargin - arrowSize.height,
contentSize.height * 2),
arrowOffsetY,
);
contentOffset = Offset(
anchorCenterX - contentSize.width / 2,
math.max(
anchorTopY -
verticalMargin -
arrowSize.height -
contentSize.height,
contentSize.height),
contentOffsetY,
);
break;
case _MenuPosition.topLeft:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment