jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.01k stars 1.58k forks source link

Get.snackbar() doesn't work successfully when starting the app for the first time. #3055

Open EricMoin opened 3 months ago

EricMoin commented 3 months ago

Description

class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return GetMaterialApp( debugShowCheckedModeBanner: false, getPages: BYRRouter.routes, initialRoute: BYRRouter.welcome, theme: ThemeData( primaryColor: BYRTheme.greyBackgroundColor, colorScheme: ColorScheme.light( primary: Colors.white ), scaffoldBackgroundColor: BYRTheme.greyBackgroundColor ), home: ScreenUtilInit( minTextAdapt: true, splitScreenMode: true, designSize: const Size(375, 812), child: WelcomeScreen(), ), ); } } /// welcome_screen.dart import 'package:flutter/material.dart'; import 'package:get/get.dart'; class WelcomeScreen extends StatefulWidget { @override State createState() => WelcomeScreenState(); } class WelcomeScreenState extends State{ @override void initState() { super.initState(); Get.snackbar('Title','message'); } @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( onTap: (){

    },
    child: Container(
      decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('resources/images/bbs_ipxmax.png'),
            fit: BoxFit.fill
          )
      ),
    ),
  )
);

} }

- But it is doesn't work successfully.The log is showed:
``` log
E/flutter (15858): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: visitChildElements() called during build.
E/flutter (15858): The BuildContext.visitChildElements() method can't be called during build because the child list is still being updated at that point, so the children might not be constructed yet, or might be old children that are going to be replaced.
E/flutter (15858): #0      Element.visitChildElements.<anonymous closure> (package:flutter/src/widgets/framework.dart:3710:7)
E/flutter (15858): #1      Element.visitChildElements (package:flutter/src/widgets/framework.dart:3719:6)
E/flutter (15858): #2      GetNavigation.overlayContext (package:get/get_navigation/src/extension_navigation.dart:1148:40)
E/flutter (15858): #3      SnackbarController._configureOverlay (package:get/get_navigation/src/snackbar/snackbar_controller.dart:91:36)
E/flutter (15858): #4      SnackbarController._show (package:get/get_navigation/src/snackbar/snackbar_controller.dart:331:5)
E/flutter (15858): #5      GetQueue._check (package:get/get_utils/src/queue/get_queue.dart:42:47)
E/flutter (15858): #6      GetQueue.add (package:get/get_utils/src/queue/get_queue.dart:29:5)
E/flutter (15858): #7      _SnackBarQueue._addJob (package:get/get_navigation/src/snackbar/snackbar_controller.dart:357:31)
E/flutter (15858): #8      SnackbarController.show (package:get/get_navigation/src/snackbar/snackbar_controller.dart:63:27)
E/flutter (15858): #9      ExtensionSnackbar.snackbar (package:get/get_navigation/src/extension_navigation.dart:465:18)
E/flutter (15858): #10     WelcomeScreenState.initState (package:byr_flutter/features/screens/login/welcome_screen.dart:22:9)
E/flutter (15858): #11     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5611:55)
E/flutter (15858): #12     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5456:5)
E/flutter (15858): #13     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4335:16)
E/flutter (15858): #14     Element.updateChild (package:flutter/src/widgets/framework.dart:3840:20)
E/flutter (15858): #15     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5505:16)
E/flutter (15858): #16     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5643:11)
E/flutter (15858): #17     Element.rebuild (package:flutter/src/widgets/framework.dart:5196:7)
E/flutter (15858): #18     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2904:19)
E/flutter (15858): #19     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:989:21)
E/flutter (15858): #20     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:448:5)
E/flutter (15858): #21     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1386:15)
E/flutter (15858): #22     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1311:9)
E/flutter (15858): #23     SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:1034:7)
E/flutter (15858): #24     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter (15858): #25     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (15858): #26     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (15858): #27     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
E/flutter (15858): 
E/flutter (15858): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: LateInitializationError: Field '_controller@954359576' has not been initialized.
E/flutter (15858): #0      SnackbarController._controller (package:get/get_navigation/src/snackbar/snackbar_controller.dart)
E/flutter (15858): #1      SnackbarController._removeEntry (package:get/get_navigation/src/snackbar/snackbar_controller.dart:314:7)
E/flutter (15858): #2      SnackbarController.close (package:get/get_navigation/src/snackbar/snackbar_controller.dart:55:5)
E/flutter (15858): #3      _SnackBarQueue._closeCurrentJob (package:get/get_navigation/src/snackbar/snackbar_controller.dart:370:29)
E/flutter (15858): #4      SnackbarController.closeCurrentSnackbar (package:get/get_navigation/src/snackbar/snackbar_controller.dart:340:26)
E/flutter (15858): #5      GetNavigation.closeCurrentSnackbar (package:get/get_navigation/src/extension_navigation.dart:1124:30)
E/flutter (15858): #6      GetNavigation.back (package:get/get_navigation/src/extension_navigation.dart:822:7)
E/flutter (15858): #7      UserSettingScreenState.build.<anonymous closure> (package:byr_flutter/features/screens/user/user_setting_screen.dart:37:32)
E/flutter (15858): #8      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1183:21)
E/flutter (15858): #9      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:315:24)
E/flutter (15858): #10     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)
E/flutter (15858): #11     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)
E/flutter (15858): #12     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)
E/flutter (15858): #13     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:670:9)
E/flutter (15858): #14     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
E/flutter (15858): #15     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
E/flutter (15858): #16     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)
E/flutter (15858): #17     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
E/flutter (15858): #18     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
E/flutter (15858): #19     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:495:19)
E/flutter (15858): #20     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)
E/flutter (15858): #21     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:430:11)
E/flutter (15858): #22     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)
E/flutter (15858): #23     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)
E/flutter (15858): #24     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)
E/flutter (15858): #25     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)
E/flutter (15858): #26     _invoke1 (dart:ui/hooks.dart:328:13)
E/flutter (15858): #27     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:429:7)
E/flutter (15858): #28     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)

Solution(not good)

GotJimmy commented 3 months ago

I had the same problem when calling snackbar from the main() function, but moving the snackbar call to onInit of a GetXController class that gets created during application startup did the trick and now works perfectly on startup.

jonataslaw commented 3 months ago

Well, let me explain what's going on:

At the time you called the snackbar, the widget tree Overlay was not ready yet. If you use the Snackbar in main(), or onInit(), or initState(), it will trigger an error, perhaps this is not so obvious, but all of this is called before the build process is completed, so how do you Will display a widget if the tree is not ready yet?

But I'm here to give you the solution:

  1. I'm using Get.snackbar() in onInit():
    • Just stop! Use in onReady, this function was created for this.
  2. I'm using Get.snackbar() in main():
    • I recommend you look for a better place to insert your snackbar, but it will work with tip 3, in the same way. So If you really need it, just follow it.
  3. I'm using it in initState (or main()), and I can't change it.
    • There is a native feature (which is also documented) that solves this with a single parameter: Get.snackbar("dsds", "dsds",instantInit: false);

instantInit: false will wait for the widget tree to be ready and send the snackbar.

Hope this helps.

GotJimmy commented 3 months ago

Thanks @jonataslaw for this precise feedback. Already implemented this with suggestions 1 & 3. Works perfectly!