Flutter - run a function every time the page changes

8,580

Solution 1

You can use inheritance

abstract class MyState<T extends StatefulWidget> extends State {
  @override
  void initState() {
    super.initState();
    //YOUR CHANGE PAGE METHOD HERE
  }
}

class YellowBird extends StatefulWidget {
  const YellowBird({ Key key }) : super(key: key);

  @override
  _YellowBirdState createState() => _YellowBirdState();
}

class _YellowBirdState extends MyState<YellowBird> {
  @override
  Widget build(BuildContext context) {
    return Container(color: const Color(0xFFFFE306));
  }
}

Solution 2

You can use implementation method didChangeDependencies this function called after initState,

flutter doc :

Subclasses rarely override this method because the framework always calls build after a dependency changes. Some subclasses do override this method because they need to do some expensive work (e.g., network fetches) when their dependencies change, and that work would be too expensive to do for every build.

Link

    @override
    void didChangeDependencies() {
      super.didChangeDependencies();
      // set your stuff here 
      }
Share:
8,580
Billy Mahmood
Author by

Billy Mahmood

Updated on December 02, 2022

Comments

  • Billy Mahmood
    Billy Mahmood over 1 year

    I want to run a function every time the page changes in my Flutter application.

    Ideally, I don't want to call this function in initState of every page, as sometimes people can forget to add the call in a new page.

    Think of it as middleware - be basically before the page loads etc, some code needs to run.

    Updated code for review

    import 'package:flutter/material.dart';
    import 'package:flutter_secure_storage/flutter_secure_storage.dart';
    import 'package:myapp/pages/login_page.dart';
    import 'package:myapp/pages/dashboard_page.dart';
    import 'package:myapp/styles/constants.dart';
    import 'package:myapp/services/auth_service.dart';
    
    Future<void> main() async {
      // create a auth service instance
      AuthService authService = AuthService(secureStorage: FlutterSecureStorage());
      bool isLoggedIn = await authService.isUserLoggedIn();
    
      // run the app
      runApp(MyApp(
        isLoggedIn: isLoggedIn,
      ));
    }
    
    class MyApp extends StatefulWidget {
      final bool isLoggedIn;
    
      MyApp({this.isLoggedIn});
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> with RouteAware {
      final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
    
      @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        routeObserver.subscribe(this, ModalRoute.of(context));
      }
    
      @override
      void dispose() {
        routeObserver.unsubscribe(this);
        super.dispose();
      }
    
      @override
      void didPush() {
        print('didPush');
      }
    
      @override
      void didPopNext() {
        print('didPopNext');
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'App NAME',
          theme: ThemeData(
            primarySwatch: Colors.green,
            primaryColor: kPrimeColour,
          ),
          home: widget.isLoggedIn == true ? DashboardPage() : LoginPage(),
          navigatorObservers: [routeObserver],
        );
      }
    }
    
    
    • Raouf Rahiche
      Raouf Rahiche almost 5 years
      The build method is responsible for changing the widget/page content. which means that you only need to call your function in the build method
    • Billy Mahmood
      Billy Mahmood almost 5 years
      Hey, my application currently has more than 8 pages, which means I have more than 8 build methods, and as the application grows, we need to make sure that this functionality runs on all new pages - is this possible, if so please can you give an example?
    • Raouf Rahiche
      Raouf Rahiche almost 5 years
      I need to exactly understand your case I think you are just looking for RouteObserver which will be triggered every time a new route/page will be pushed or poped
    • Billy Mahmood
      Billy Mahmood almost 5 years
      This is just what I need, the docs on it are slightly over my head, however, I will try to make sense of it - and if I cant, I will be back
    • Billy Mahmood
      Billy Mahmood almost 5 years
      So I am able to add the routeObserver to main() - am not sure how to add the event listeners, without amending existing pages, any suggestions on this please?
    • Raouf Rahiche
      Raouf Rahiche almost 5 years
      Check out this example
  • Billy Mahmood
    Billy Mahmood almost 5 years
    Hey please check my updated code, is that what you mean?