I am making an app where i want to have dark theme for app on switch.I have written the code and is working fine but just for one page.When i go back and open that page again it shows "BAD STATE ERROR". when i searched on stackoverflow, many of them suggested to use shared preferences.But i am unable to implement it.

CODE

    class Settings extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    // TODO: implement build
    return StreamBuilder(

      stream: bloc.darkThemeEnabled,
      initialData: false,
      builder: (context,snapshot) => MaterialApp(
        debugShowCheckedModeBanner: false ,
        theme: snapshot.data?ThemeData.dark():ThemeData.light(),
        home: HomePage(snapshot.data),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
 final bool darkThemeEnabled;

  HomePage(this.darkThemeEnabled);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        title: Text('Settings'),
      ),
      body: ListView(
        children: <Widget>[
          ListTile(
              title: Text("Dark Theme",style:
              TextStyle(
                  fontSize: 20.0
              ),),
              trailing: Switch(
                value: darkThemeEnabled,
                onChanged:bloc.changeTheme,
              )
          )],
      ),
    );
  }
}

class Bloc{
  final _themecontroller = StreamController<bool>();
  get changeTheme => _themecontroller.sink.add;
  get darkThemeEnabled => _themecontroller.stream;

}

final bloc = Bloc();


Solution 1: Len_X

Adding shared prefs:

add shared_preferences: ^0.5.4+8 to you pubspec.yaml

import 'package:shared_preferences/shared_preferences.dart'; in your class

to store call

final prefs = await SharedPreferences.getInstance();
prefs.setString(key, value);

to read call

final prefs = await SharedPreferences.getInstance();
var value = prefs.getString(key);

to remove call

final prefs = await SharedPreferences.getInstance();
prefs.remove(key);

key is the key of the value and value is the value you want to store In your instance you can use key == theme , value == dark/light


Solution 2: Kahou

Exampe on DartPad

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ThemeMode _themeMode = ThemeMode.light;

  _handleThemeModeChanged(ThemeMode mode) {
    setState(() {
      _themeMode = mode;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: _themeMode,
      debugShowCheckedModeBanner: false,
      home: HomePage(
          themeMode: _themeMode, onThemeModeChanged: _handleThemeModeChanged),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key key, this.themeMode, this.onThemeModeChanged})
      : super(key: key);

  final ThemeMode themeMode;
  final ThemeModeChanged onThemeModeChanged;

  onSwitch(bool value) {
    final newThemeMode = value ? ThemeMode.dark : ThemeMode.light;

    onThemeModeChanged(newThemeMode);
  }

  @override
  Widget build(BuildContext context) {
    final isDarkMode = themeMode == ThemeMode.dark;

    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
      ),
      body: ListView(
        children: <Widget>[
          ListTile(
              title: Text(
                "Dark Theme",
                style: TextStyle(fontSize: 20.0),
              ),
              trailing: Switch(value: isDarkMode, onChanged: onSwitch))
        ],
      ),
    );
  }
}