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

Jose Alba
Jose Alba
Mar 2, 2020 · 4 min read

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.

Flutter

Flutter is Google's mobile UI framework for crafting…

Flutter

Flutter is Google's mobile UI framework for crafting high-quality native interfaces on iOS and Android in record time. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Learn more at https://flutter.dev

Jose Alba

Written by

Jose Alba

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

Flutter

Flutter is Google's mobile UI framework for crafting high-quality native interfaces on iOS and Android in record time. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Learn more at https://flutter.dev

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store