How to float an overlay widget over a (possibly transformed) UI widget

Jose Alba
Flutter
Published in
4 min readMar 2, 2020

About the author: Jose recently graduated from university and now works on Material, a design system that helps teams build high-quality digital experiences. Jose’s team maintains the Flutter material library.

Say you have a widget in your app’s UI and you want to overlay a floating widget on top of that widget. Maybe that widget is rotated or has other transforms applied. How do you convey the position and transform information of the UI widget to the corresponding widget in the overlay?

You can do this using the CompositedTransformTarget, CompositedTransformWidget, LayerLink, Overlay, and OverlayEntry widgets.

In Flutter, the overlay lets you print visual elements on top of other widgets by inserting them into the overlay’s stack. You insert a widget into the overlay using an OverlayEntry and you use Positioned and AnimatedPositioned to choose where the entry is positioned within the overlay. This is useful when you need an item to appear on top of another widget (similar to the Stack widget) but you can use this widget anywhere without having to modify your entire codebase.

As described in this article, a programmer needs to implement an autosuggestion feature to a text field widget to an existing page. They could implement this feature using a stack but, as mentioned in the article, this approach can be: intrusive, rigorous, error-prone, and just feels wrong. Instead of redesigning your whole screen into a stack, you can use the overlay widget to add this effect. This scenario can happen any time a developer has to implement a new feature on an existing route.

Using an Overlay might seem intuitive but can be challenging to implement in Flutter. The overlay entry must be inserted using a callback method. Plus you need to keep a reference to the overlay entry since you remove the entry using the reference and not the context of the overlay. Also, if you need the overlay entry’s position and transformation to be dependent on another widget that is not in the overlay, it can get confusing. This is because the context of the overlay’s MediaQuery is different from the regular context. You may have seen this when using padding or margin in a Widget before making a call to the Overlay. Luckily, Flutter already takes care of these details for you.

If an overlay entry needs to follow a ‘target’ that is not on the overlay stack you can use CompositedTransformTarget, CompositedTransformFollower, and LayerLink to “glue” the widgets together To do this you need to:

  • Wrap the widget on the overlay with a CompositedTransformFollower.
  • The follower has to be a descendant of CompositedTransformTarget.
  • The target Widget must be wrapped with a CompositedTransformTarget.
  • A LayerLink instance glues the follower and target together.

In the following GIF, the blue container is not on the overlay but the green container is. The blue container is a child of CompositedTransformTarget and the green container is the child of CompostedTransformFollower. They are linked together using the same LayerLink instance. Note how the green overlay widget is aware of the bounds of the blue UI widget, even though the blue widget is not in the overlay:

Try it yourself using this DartPad instance. The example code is as follows:

Code by Hans Muller

This example shows how to use these widgets together. To see the true power of these widgets, apply a Transformation to the CompositedTransformTarget. You will notice that the green overlay widget is also impacted by this transformation, thanks to their shared LayerLink widget.

In the following GIF, the blue container is not on the overlay but the green container is. This time the CompositedTransformTarget has been rotated. As you can see, even though the CompositeTransformFollower is on the overlay stack, it still knows where the target is and any transformations that have been applied to it.

Try it yourself using this DartPad instance. The example code is as follows:

Code by Hans Muller

Conclusion

When implementing a UI that floats widgets on top of other widgets, using the overlay and linking the widgets together is a straightforward and powerful approach. In this article, you learned how to use a LayerLink to glue these widgets together. Now go forth and create your beautiful UI!

To learn more about Jose, visit his pages on GitHub, LinkedIn, YouTube, and Instagram.

--

--

Jose Alba
Flutter

Recently graduated from university and now works on maintaining the Flutter Material Library.