0
votes

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);
        },
      ),
    );
  }
}
1
why not call navigator.push when id is 2 in onTap itself and setState maybe for the rest of them? Makes sense as builder is supposed to return a widget, which is not the case when page==2Joy Terence
Mr. Terence, it works! thanks a lot.KAMDeveloper
Glad I could help. Posted the same as an answer to help those come here.Joy Terence
It's my pleasure, and I would be even more honored if you would allow me to be in touch with you!KAMDeveloper
sure @KAMDeveloper, just connect with me on linkedin :)Joy Terence

1 Answers

0
votes

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