safePositionRelatedTo method

Offset? safePositionRelatedTo(
  1. GlobalKey<State<StatefulWidget>> targetKey, {
  2. Alignment position = Alignment.topCenter,
  3. Offset translate = Offset.zero,
  4. Offset padding = const Offset(4, 4),
  5. BuildContext? context,
  6. Offset screenCorrection = Offset.zero,
})

Same as calling positionRelatedTo, but the returned offset will never let the widget be positioned outside the screen.

screenCorrection should be used to adapt the device screen size to the actual Overlay.of(context) "available area". For example, if the MaterialApp is wrapped inside a builder that provide widget outside the app, the screenCorrection should be used to correct the screen size.

Implementation

Offset? safePositionRelatedTo(
  GlobalKey targetKey, {
  Alignment position = Alignment.topCenter,
  Offset translate = Offset.zero,
  Offset padding = const Offset(4, 4),
  BuildContext? context,
  Offset screenCorrection = Offset.zero,
}) {
  final Offset? _position = positionRelatedTo(targetKey, position: position, translate: translate, padding: padding);
  if (_position == null) return null;
  if (currentContext == null && context == null) return _position;

  Size _screenSize = MediaQuery.of(currentContext ?? context!).size;
  _screenSize = Size(_screenSize.width - screenCorrection.dx, _screenSize.height - screenCorrection.dy);

  final Rect _updatedTooltipRect = globalPaintBounds!.translate(_position.dx - screenCorrection.dx, _position.dy - screenCorrection.dy);

  double _dx = 0;
  double _dy = 0;

  if (_updatedTooltipRect.left + _updatedTooltipRect.width > _screenSize.width) {
    _dx = _screenSize.width - (_updatedTooltipRect.left + _updatedTooltipRect.width + 16);
  } else if (_updatedTooltipRect.left < 0) {
    _dx = -_updatedTooltipRect.left + 16;
  }

  if (_updatedTooltipRect.top + _updatedTooltipRect.height > _screenSize.height) {
    _dy = _screenSize.height - (_updatedTooltipRect.top + _updatedTooltipRect.height + 16);
  } else if (_updatedTooltipRect.top < 0) {
    _dy = -_updatedTooltipRect.top + 16;
  }

  return _position + Offset(_dx, _dy) - screenCorrection;
}