Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding OverlayEntry in Flutter

Tags:

flutter

I am trying to insert a Container to the Overlay, but I had an error with this code.

class _MyHomePageState extends State<MyHomePage> {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final entry = OverlayEntry(builder: (BuildContext overlayContext) {
      return Container(
        height: 50.0,
        width: 50.0,
        color: Colors.blue,
      );
    });
    _addOverlay(entry);
  }

  void _addOverlay(OverlayEntry entry) async {
    Overlay.of(context).insert(entry);
  }

  @override
  Widget build(BuildContext context) {
   return Scaffold(
      appBar: AppBar(
        title: Text('Flutter'),
      ),
      body: Center(),
    );
  }
}

This is error

setState() or markNeedsBuild() called during build. This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase...

Thank you in advance.

like image 494
Huy Hoàng Avatar asked Jul 24 '18 08:07

Huy Hoàng


People also ask

How do you use OverlayEntry in Flutter?

OverlayEntry is used to insert a widget into the Overlay, then Positioned or AnimatedPositioned is used to determine where it will enter within the Overlay. This is useful when you require an item to appear on top of another widget (similar to the Stack widget) without modifying your entire codebase.

How do you overlay the button in Flutter?

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.

What is overlay support in Flutter?

Overlays let independent child widgets float visual elements on top of other widgets by inserting them into the overlay's Stack. This article discusses the implementation of Overlays in Flutter.


Video Answer


2 Answers

Since the last update to flutter 0.8.1 I noticed this change too. I fixed this to add the overlay after a minimal delay

Timer.run(() { Overlay.of(context).insert(calendarOverlay);});

Now this works but it feels like a hack...

So in my build i use this code when the overlay should present itself..

If anyone has a better solution, I am interested ;-)

John

UPDATE: I found this code to be working too:

final overlay = Overlay.of(context);
WidgetsBinding.instance.addPostFrameCallback((_) => overlay.insert(entry));

It saves me from including timers...

like image 57
John Gorter Avatar answered Oct 25 '22 23:10

John Gorter


Just share some of my findings. I am about to implement overlay in my app too. So found this SO question by searching.

Many people build overlay before the normal widget. For example, in your code, the overlay insert in didChangeDependencies is called before building the Scaffold. This is the cause of all the async problems. I found people do this (couple the overlay insert and corresponding normal widget in a stateful widget) is because they want to find the corresponding child widget's position, but the child widget is build after the overlay insert call, thus the overlay insert has to be in an async function.

But If you just call overlay insert after building the normal widget (make overlay insert call independent from building the base widget. Separate/decouple them), you won't need any async or Timer functions at all. In my current implementation, I separate them just to make the code safe (I feel it's safer). So no need for any async calls.

like image 24
sgon00 Avatar answered Oct 25 '22 23:10

sgon00