Search code examples
fluttersettingssetstateapplication-settings

Flutter: Android: How to call setState() from another file?


For applying app's setting configuration to take effect around app i need to trigger main's setState from appSettings file, how to do so?

Files code:

for main.dart

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Builder(
        builder: (context) => Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(isVibrationEnabled
                    ? "Vibration is enabled"
                    : "Vibration is disabled"),
                MaterialButton(
                  color: Colors.grey,
                  child: Text("Open app setting"),
                  onPressed: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => AppSettings(),
                      ),
                    );
                  },
                )
              ],
            ),
          ),
        ),
      ),
    );

for globalVariables.dart

bool isVibrationEnabled = false;

for appSettings.dart

class _AppSettingsState extends State<AppSettings> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FlatButton(
            color: Colors.grey,
            child: Text(
                isVibrationEnabled ? "Disable Vibration" : "Enable Vibration"),
            onPressed: () {
              setState(() {
                isVibrationEnabled
                    ? isVibrationEnabled = false
                    : isVibrationEnabled = true;
              });
              //What to do here to trigger setState() in main.dart flie
              //for displaying "Vibration is enabled" or "Vibration is disabled"
              //acording to the value of bool variable which is in globalVariable.dart file.
            },
          ),
        ),
      ),
    );

i have seen other answer on stackoverflow but none of them are easy to understand, if someone can answer in a easy way please


Solution

  • For your specific use case, I think best is to use a state management solution like Provider, BLoC, or GetX. Docs here: https://flutter.dev/docs/development/data-and-backend/state-mgmt/options

    If you want something quick and easy, you can pass the value you're listening to and a function containing setState to your new page. Normally you'd do this with a child widget rather than new page, so it might get a bit complicated -- you'll need to rebuild the entire page after the setState. Easiest way I can think of doing that is with Navigator.pushReplacement.

    Some code (I wrote this in stackoverflow not my IDE so probably has errors):

    class AppSettings extends StatefulWidget {
        final Function callback;
        final bool isVibrationEnabled;
    
        AppSettings({
            @required this.callback,
            @required this.isVibrationEnabled,
        });
    }
    

    ...

    In your AppSettingsState use:

            FlatButton(
                color: Colors.grey,
                child: Text(
                    widget.isVibrationEnabled ? "Disable Vibration" : "Enable Vibration"),
                onPressed: () => widget.callback(),
              ),
    

    And in your main file, when creating your appsettings use something like:

               MaterialButton(
                  color: Colors.grey,
                  child: Text("Open app setting"),
                  onPressed: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => AppSettings(
                            isVibrationEnabled: isVibrationEnabled,
                            callback: callback,
                         ),
                      ),
                    );
                  },
                )
    
                void Function callback() {
                   setState(() => isVibrationEnabled = !isVibrationEnabled);
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                        builder: (context) => AppSettings(
                            isVibrationEnabled: isVibrationEnabled,
                            callback: callback,
                         ),
                      ),
                    );
                  }
    

    Again, you should probably use a state management solution for this specific use case. Rebuilding a page from another page seems messy. But it should work. And yes, you're using the callback within your callback. So you may need to put the callback near the top of your file, or outside the main function to make it work right.