Fix: Submenu anchor misaligned with child panel in web (Resolved #151081) - The issue comes from different in calculating the position of the menu in web and mobile. - The calculation is currently base on function `getPositionForChild()` inside `_MenuLayout` in `menu_anchor.dart`, which base on the `anchorRect` - The calculation of `anchorRect` is from `upperLeft` and `bottomRight` - `upperLeft` is result of `localToGlobal()` function, which take the `point` arguments to be the base line. Right now, `point` is refer to `Offset.zero`, but it should not be Offset.zero since we having `densityAdjustment`, which is different between web and mobile - Change `point` from `Offset.zero` to `Offset(dx, -dy)` should fix the error. Use `dx` instead of `-dx` since `dx` already be recalculated refer to the above comment on `densityAdjustment`. Before:  After:  Issue: https://github.com/flutter/flutter/issues/151081
This commit is contained in:
parent
ceced3984f
commit
bc3d2feb9c
@ -3529,12 +3529,6 @@ class _Submenu extends StatelessWidget {
|
||||
final VisualDensity visualDensity =
|
||||
effectiveValue((MenuStyle? style) => style?.visualDensity) ?? Theme.of(context).visualDensity;
|
||||
final AlignmentGeometry alignment = effectiveValue((MenuStyle? style) => style?.alignment)!;
|
||||
final BuildContext anchorContext = anchor._anchorKey.currentContext!;
|
||||
final RenderBox overlay = Overlay.of(anchorContext).context.findRenderObject()! as RenderBox;
|
||||
final RenderBox anchorBox = anchorContext.findRenderObject()! as RenderBox;
|
||||
final Offset upperLeft = anchorBox.localToGlobal(Offset.zero, ancestor: overlay);
|
||||
final Offset bottomRight = anchorBox.localToGlobal(anchorBox.paintBounds.bottomRight, ancestor: overlay);
|
||||
final Rect anchorRect = Rect.fromPoints(upperLeft, bottomRight);
|
||||
final EdgeInsetsGeometry padding =
|
||||
resolve<EdgeInsetsGeometry?>((MenuStyle? style) => style?.padding) ?? EdgeInsets.zero;
|
||||
final Offset densityAdjustment = visualDensity.baseSizeAdjustment;
|
||||
@ -3547,6 +3541,12 @@ class _Submenu extends StatelessWidget {
|
||||
final EdgeInsetsGeometry resolvedPadding = padding
|
||||
.add(EdgeInsets.fromLTRB(dx, dy, dx, dy))
|
||||
.clamp(EdgeInsets.zero, EdgeInsetsGeometry.infinity);
|
||||
final BuildContext anchorContext = anchor._anchorKey.currentContext!;
|
||||
final RenderBox overlay = Overlay.of(anchorContext).context.findRenderObject()! as RenderBox;
|
||||
final RenderBox anchorBox = anchorContext.findRenderObject()! as RenderBox;
|
||||
final Offset upperLeft = anchorBox.localToGlobal(Offset(dx, -dy), ancestor: overlay);
|
||||
final Offset bottomRight = anchorBox.localToGlobal(anchorBox.paintBounds.bottomRight, ancestor: overlay);
|
||||
final Rect anchorRect = Rect.fromPoints(upperLeft, bottomRight);
|
||||
|
||||
return Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
|
@ -256,13 +256,13 @@ void main() {
|
||||
expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(105.0, 0.0, 695.0, 72.0)));
|
||||
expect(
|
||||
tester.getRect(find.widgetWithText(MenuItemButton, TestMenu.subMenu10.label)),
|
||||
equals(const Rect.fromLTRB(249.0, 80.0, 483.0, 136.0)),
|
||||
equals(const Rect.fromLTRB(257.0, 80.0, 491.0, 136.0)),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(
|
||||
find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1),
|
||||
),
|
||||
equals(const Rect.fromLTRB(241.0, 64.0, 491.0, 264.0)),
|
||||
equals(const Rect.fromLTRB(249.0, 64.0, 499.0, 264.0)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -3181,7 +3181,7 @@ void main() {
|
||||
equals(const <Rect>[
|
||||
Rect.fromLTRB(161.0, 0.0, 639.0, 40.0),
|
||||
Rect.fromLTRB(265.0, 40.0, 467.0, 160.0),
|
||||
Rect.fromLTRB(467.0, 72.0, 707.0, 232.0),
|
||||
Rect.fromLTRB(467.0, 80.0, 707.0, 240.0),
|
||||
]),
|
||||
);
|
||||
});
|
||||
@ -3197,7 +3197,7 @@ void main() {
|
||||
equals(const <Rect>[
|
||||
Rect.fromLTRB(161.0, 0.0, 639.0, 40.0),
|
||||
Rect.fromLTRB(333.0, 40.0, 535.0, 160.0),
|
||||
Rect.fromLTRB(93.0, 72.0, 333.0, 232.0),
|
||||
Rect.fromLTRB(93.0, 80.0, 333.0, 240.0),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
@ -280,11 +280,11 @@ void main() {
|
||||
expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(228.0, 0.0, 572.0, 48.0)));
|
||||
expect(
|
||||
tester.getRect(find.text(TestMenu.subMenu10.label)),
|
||||
equals(const Rect.fromLTRB(366.0, 68.0, 559.0, 82.0)),
|
||||
equals(const Rect.fromLTRB(372.0, 68.0, 565.0, 82.0)),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1)),
|
||||
equals(const Rect.fromLTRB(346.0, 48.0, 579.0, 186.0)),
|
||||
equals(const Rect.fromLTRB(352.0, 48.0, 585.0, 186.0)),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user