Search code examples
flutterdartroutesappbarscaffold

Add to Scaffold Appbar a click counter with multiple pages


Hello I'm creating an app with multiple pages using Navigators and routes. I would like to add to the Scaffold Appbar a counter that increment every time a finger clicks on a screen button (also if they are more then one button present in the page). Also if I change the pages, this counter must increase. Can you help me to understand the issue? I'm learing so probably the structure could be a "beginner" version. Thanks.


Solution

  • As @Randal Schwartz commented, we could take advantage of the onGenerateRoute property of the MaterialApp class:

    runApp(MaterialApp(
            home: BuilderPage(LoginArguments(false)),
            onGenerateRoute: generateRoute
    ));
    

    By defining a custom generateRoute function:

    int counter = 0; // global variable outside of the classes
    
    Route<dynamic> generateRoute(RouteSettings settings) {
      switch (settings.name) {
        case 'home':
          counter++;
          return MaterialPageRoute(builder: (_) => HomeScreen());
        case 'login':
          counter++;
          return MaterialPageRoute(builder: (_) => LoginScreen());
        case 'register':
          counter++;
          return MaterialPageRoute(builder: (_) => RegisterScreen());
      }
    }
    

    The counter could be then displayed by the Widgets by loading it in their state:

    class HomeScreen extends StatefulWidget {
      const HomeScreen({ Key key }) : super(key: key);
    
      @override
      _HomeScreenState createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
    
      int _counter;
    
      @override
      void initState() {
        super.initState();
        setState(() => _counter = counter);
      }
    
      void _increaseCounter() {
         counter++;
         setState(() => _counter++);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
           appBar: AppBar(child: Text(_counter.toString())),
           body: SafeArea(
                   child: Center(child: 
                      GestureDetector(
                         onTap: () { _increaseCounter(); }, 
                         child: Text('test'),
                     ),
                  ),
               ),
           ),
        );
      }
    }
    

    NB: this solution is not optimal. Please make sure to consider more advanced state management architectures, like BLoC, to better manage the data syncronization between different Widgets in the app.