Search code examples
flutterdartflutter-navigation

Flutter - call Navigator inside switch which it is inside builder


I want to navigate to QrScan screen once the icons get pressed, instead, I got an error!! setState() or markNeedsBuild() called during build I want to navigate to that screen and get data from QR Codes, after that I want this data to be shown on another screen!

It says:

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.

The widget on which setState() or markNeedsBuild() was called was: Overlay- [LabeledGlobalKey#a5a46]

The widget which was currently being built when the offending call wasmade was: builder

class MainTabsScreen extends StatefulWidget {
  @override
  _MainTabsScreenState createState() => _MainTabsScreenState();
}

class _MainTabsScreenState extends State<MainTabsScreen> {
  int page = 3;

  void _openScanner() {
    Navigator.push(context, MaterialPageRoute(builder: (context) => QrScan()));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Builder(
          builder: (context) {
            switch (page) {
              case 0:
                return ExploreScreen();
              case 1:
                return OffersScreen();
              case 2:
                _openScanner();
                break;
              case 3:
                return AltersScreen();
              case 4:
                return ChatsScreen();
              default:
                return ExploreScreen();
            }
          },
        ),
      ),
      bottomNavigationBar: ConvexAppBar(
        top: -20.0,
        backgroundColor: Colors.white,
        activeColor: Color(0xBB0BCC83),
        color: Color(0xBB0BCC83),
        height: 53.0,
        elevation: 0.0,
        initialActiveIndex: 3,
        items: [
          TabItem(
            icon: Icons.home,
            title: 'Home',
          ),
          TabItem(
            icon: Icons.list,
            title: 'Offers',
          ),
          TabItem(
            icon: Icons.qr_code,
            title: 'Scan',
          ),
          TabItem(
            icon: Icons.add_alert,
            title: 'Notification',
          ),
          TabItem(
            icon: Icons.chat,
            title: 'Chats',
          ),
        ],
        onTap: (id) {
          setState(() => page = id);
        },
      ),
    );
  }
}

Solution

  • As discussed in comments, a solution was to call the navigator.push when id == 2 within the onTap function.