talamaska / onboarding_overlay

MIT License
42 stars 22 forks source link

How to wait for the page widgets to load? #56

Open rignaneseleo opened 10 months ago

rignaneseleo commented 10 months ago

Hi, I'm using this library on the home screen of an app. The homescreen has some widgets that get loaded dynamically based on what's fetched on the server.

Each home widget has the following build logic:

@override
  Widget build(BuildContext context, WidgetRef ref) {
    if (qod == null) {
      return const SizedBox();
    }

    //return the actual widget
  }

If I wrap this whole widget into a Focus node, I get only a tiny dot highlighted (which probably corresponds to the empty SizedBox(). If I wrap only the actual box, I get the grey overlay without any highlight at all.

I guess this happens because at the time the Onboarding widget is initialized, the focusnodes are wrapping something that either will change (SizedBox) or doesn't exists yet (the actual widget).

How can I solve this problem?

I tried to call the show() function after a delay, but nothing has changed:

 @override
  void initState() {
    super.initState();

    Future.delayed(const Duration(milliseconds: 500), () {
      final OnboardingState? onboarding = Onboarding.of(context);
      if (onboarding != null) {
        onboarding.show();
      }
    });
  }
TheMaverickProgrammer commented 4 months ago

Did you ever find a solution? I'm having a similar problem.

chriscarman-mp commented 4 weeks ago

Same here, on Android it seems fine but there's an issue on iOS which has slightly longer/different page load animations. I can remove the animations but would rather find a better solution, and not just using a delay and it's inconsistent and inaccurate.

chriscarman-mp commented 4 weeks ago

So, I may have stumbled across a solution

Future<void> waitForRenderSettled() async {
    // Loop until there are no scheduled frames
    while (SchedulerBinding.instance.hasScheduledFrame) {
      // Wait for the end of the current frame
      await SchedulerBinding.instance.endOfFrame;
    }
  }

Use it like this

await waitForRenderSettled();

// Do your thing ...