Commit ded174bb authored by skeyboy's avatar skeyboy

文本消息长按菜单

parent c69c35c4
...@@ -115,6 +115,7 @@ class _CustomPopupMenuState extends State<CustomPopupMenu> { ...@@ -115,6 +115,7 @@ class _CustomPopupMenuState extends State<CustomPopupMenu> {
), ),
child: CustomMultiChildLayout( child: CustomMultiChildLayout(
delegate: _MenuLayoutDelegate( delegate: _MenuLayoutDelegate(
itemSize: _childBox?.size ?? Size.zero,
tapedPoint: _controller?.localPosition ?? Offset.zero, tapedPoint: _controller?.localPosition ?? Offset.zero,
anchorSize: _childBox!.size, anchorSize: _childBox!.size,
anchorOffset: _childBox!.localToGlobal( anchorOffset: _childBox!.localToGlobal(
...@@ -289,9 +290,14 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { ...@@ -289,9 +290,14 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
required this.anchorOffset, required this.anchorOffset,
required this.verticalMargin, required this.verticalMargin,
required this.tapedPoint, required this.tapedPoint,
required this.itemSize,
this.position, this.position,
}); });
// 消息列表的的大小
final Size itemSize;
/// 消息列表点击的位置
final Offset tapedPoint; final Offset tapedPoint;
final Size anchorSize; final Size anchorSize;
final Offset anchorOffset; final Offset anchorOffset;
...@@ -328,7 +334,8 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { ...@@ -328,7 +334,8 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
BoxConstraints.loose(size), BoxConstraints.loose(size),
); );
} }
print("文本内容大小 $size $contentSize $anchorOffset 点击位置$tapedPoint"); print(
"文本内容大小 $size $contentSize$itemSize $anchorOffset 点击位置$tapedPoint");
bool isTop = false; bool isTop = false;
if (position == null) { if (position == null) {
// auto calculate position // auto calculate position
...@@ -336,6 +343,13 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { ...@@ -336,6 +343,13 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
} else { } else {
isTop = position == PreferredPosition.top; 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) { if (anchorCenterX - contentSize.width / 2 < 0) {
menuPosition = isTop ? _MenuPosition.topLeft : _MenuPosition.bottomLeft; menuPosition = isTop ? _MenuPosition.topLeft : _MenuPosition.bottomLeft;
} else if (anchorCenterX + contentSize.width / 2 > size.width) { } else if (anchorCenterX + contentSize.width / 2 > size.width) {
...@@ -373,19 +387,31 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { ...@@ -373,19 +387,31 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate {
); );
break; break;
case _MenuPosition.topCenter: 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( arrowOffset = Offset(
anchorCenterX - arrowSize.width / 2, anchorCenterX - arrowSize.width / 2,
math.max(anchorTopY - verticalMargin - arrowSize.height, arrowOffsetY,
contentSize.height * 2),
); );
contentOffset = Offset( contentOffset = Offset(
anchorCenterX - contentSize.width / 2, anchorCenterX - contentSize.width / 2,
math.max( contentOffsetY,
anchorTopY -
verticalMargin -
arrowSize.height -
contentSize.height,
contentSize.height),
); );
break; break;
case _MenuPosition.topLeft: 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