onExit property Null safety

PointerExitEventListener? onExit
final

Triggered when a mouse pointer has exited this widget when the widget is still mounted.

This callback is triggered when the pointer, with or without buttons pressed, has stopped being contained by the region of this widget, except when the exit is caused by the disappearance of this widget. More specifically, this callback is triggered by the following cases:

  • A pointer that is hovering this widget has moved away.
  • A pointer that is hovering this widget has been removed.
  • This widget, which is being hovered by a pointer, has moved away.

And is not triggered by the following case:

  • This widget, which is being hovered by a pointer, has disappeared.

This means that a MouseRegion.onExit might not be matched by a MouseRegion.onEnter.

This restriction aims to prevent a common misuse: if State.setState is called during MouseRegion.onExit without checking whether the widget is still mounted, an exception will occur. This is because the callback is triggered during the post-frame phase, at which point the widget has been unmounted. Since State.setState is exclusive to widgets, the restriction is specific to MouseRegion, and does not apply to its lower-level counterparts, RenderMouseRegion and MouseTrackerAnnotation.

There are a few ways to mitigate this restriction:

  • If the hover state is completely contained within a widget that unconditionally creates this MouseRegion, then this will not be a concern, since after the MouseRegion is unmounted the state is no longer used.
  • Otherwise, the outer widget very likely has access to the variable that controls whether this MouseRegion is present. If so, call onExit at the event that turns the condition from true to false.
  • In cases where the solutions above won't work, you can always override State.dispose and call onExit, or create your own widget using RenderMouseRegion.

The following example shows a blue rectangular that turns yellow when hovered. Since the hover state is completely contained within a widget that unconditionally creates the MouseRegion, you can ignore the aforementioned restriction.
To create a local project with this code sample, run:
flutter create --sample=widgets.MouseRegion.onExit.1 mysample

The following example shows a widget that hides its content one second after being hovered, and also exposes the enter and exit callbacks. Because the widget conditionally creates the MouseRegion, and leaks the hover state, it needs to take the restriction into consideration. In this case, since it has access to the event that triggers the disappearance of the MouseRegion, it simply trigger the exit callback during that event as well.
To create a local project with this code sample, run:
flutter create --sample=widgets.MouseRegion.onExit.2 mysample

The time that this callback is triggered is always between frames: either during the post-frame callbacks, or during the callback of a pointer event.

See also:

Implementation

final PointerExitEventListener? onExit;