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

602

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.

Share:
602
Anil Shrivastav
Author by

Anil Shrivastav

I am curious about checking my creativity level in app development field.

Updated on November 28, 2022

Comments

  • Anil Shrivastav
    Anil Shrivastav over 1 year

    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

    • fartem
      fartem about 3 years
      You should notify all widgets that listen a global variable that a value changed. For example, you can use Provider plugin for it.
    • Anil Shrivastav
      Anil Shrivastav about 3 years
      fartem, if this is proper way of doing so, could you please tell me how can i use Provider package by editing my code as i am new to flutter
    • fartem
      fartem about 3 years
      You can start with this article.
  • Ovidius Mazuru
    Ovidius Mazuru about 3 years
    Actually on 2nd thoguht this probably won't work. You're on a new page, so I don't think yoru old page is still in memory. I'll leave this answer up cuz I think the idea is useful -- you can do something similar with child widgets / parent widgets. To make this work with your current sitaution, can turn AppSettings into a child widget or dialogue or something like that rather than new page. Or you can navigate back to main and forward again, but that seems pointless. Just use a state management solution, dude