【问题标题】:Flutter switch toggles off on its own颤振开关自行关闭
【发布时间】:2020-07-02 16:23:30
【问题描述】:

我创建了一个 Flutter 入门工具包,允许我在应用内切换主题。

现在效果很好,但有一个小问题。

我已将切换按钮放在设置屏幕中, 但是当我转到另一个屏幕然后返回设置屏幕时 - 开关按钮似乎会自行进入关闭模式。

我附上一张图片和my code on github,以便你们明白我的意思。

class ThemeSwitchState extends State {
  bool switchControl = false;

  Future<bool> darkMode() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    return sharedPreferences.getBool("isDark");
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<bool>(
      future: darkMode(),
      builder: (context, _snapshot) {
        return Transform.scale(
          scale: 1.5,
          child: Switch(
            value: _snapshot.data ?? false,
            onChanged: (value) {
              save(value);
              setState(() {

              });
            },
            activeColor: CustomColors().duskBlue,
            activeTrackColor: CustomColors().noroGrey,
            inactiveThumbColor: CustomColors().lureGrey,
            inactiveTrackColor: CustomColors().noroGrey,
          ),
        );
      },
    );
  }

  void save(bool value) async{
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    await sharedPreferences.setBool("isDark", value);
  }

  void toggleSwitch(bool value) {
    ThemeChanger _themeChanger =
        Provider.of<ThemeChanger>(context, listen: false);

    if (switchControl == false) {
      setState(() {
        switchControl = true;
      });
      print('Theme is Dark');

      _themeChanger.setTheme(CustomThemes.darkTheme.copyWith(
          textTheme:
              CustomThemes.darkTextTheme(CustomThemes.darkTheme.textTheme)));
    } else {
      setState(() {
        switchControl = false;
      });
      print('Theme is Light');

      _themeChanger.setTheme(CustomThemes.lightTheme.copyWith(
          textTheme:
              CustomThemes.lightTextTheme(CustomThemes.lightTheme.textTheme)));
    }
  }
}

【问题讨论】:

    标签: android ios flutter dart


    【解决方案1】:

    您可以使用https://pub.dev/packages/shared_preferences中的SharedPreferences 保存 CheckBox

    的最后一个值

    我写了一个例子

    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    class Settings extends StatefulWidget {
      @override
      _SettingsState createState() => _SettingsState();
    }
    
    class _SettingsState extends State<Settings> {
    
      Future<bool> darkMode() async{
        SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
        return sharedPreferences.getBool("isNight");
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              children: <Widget>[
                Text("Night Mode"),
                FutureBuilder<bool>(
                  future: darkMode(),
                  builder: (context, _snapshot){
                    return Checkbox(
                      value: _snapshot.data ?? false,
                      onChanged: (value){
                        save(value);
                        setState(() {
                           toggleSwitch(value);
                        });
                      },
                    );
                  },
                )
              ],
            ),
          ),
        );
      }
    
    
      void save(bool value) async{
        SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
        await sharedPreferences.setBool("isNight", value);
      }
    }
    
    

    编辑:带开关

    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    class Settings extends StatefulWidget {
      @override
      _SettingsState createState() => _SettingsState();
    }
    
    class _SettingsState extends State<Settings> {
    
      Future<bool> darkMode() async{
        SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
        return sharedPreferences.getBool("isNight");
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              children: <Widget>[
                Text("Night Mode"),
                FutureBuilder<bool>(
                  future: darkMode(),
                  builder: (context, _snapshot){
                    return Switch(
                      value: _snapshot.data ?? false,
                      onChanged: (value){
                        save(value);
                        setState(() {
    
                        });
                      },
                    );
                  },
                )
              ],
            ),
          ),
        );
      }
    
    
      void save(bool value) async{
        SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
        await sharedPreferences.setBool("isNight", value);
      }
    }
    

    UPDATE 使用 value 代替 switchControl

    
      void toggleSwitch(bool value) {
        ThemeChanger _themeChanger =
            Provider.of<ThemeChanger>(context, listen: false);
    
        if (value) {
          setState(() {
            switchControl = true;
          });
          print('Theme is Dark');
    
          _themeChanger.setTheme(CustomThemes.darkTheme.copyWith(
              textTheme:
                  CustomThemes.darkTextTheme(CustomThemes.darkTheme.textTheme)));
        } else {
          setState(() {
            switchControl = false;
          });
          print('Theme is Light');
    
          _themeChanger.setTheme(CustomThemes.lightTheme.copyWith(
              textTheme:
                  CustomThemes.lightTextTheme(CustomThemes.lightTheme.textTheme)));
        }
      }
    }
    

    【讨论】:

    • 这不适用于我的开关,我按照你说的做了,但仍然
    • 使用复选框然后...就像我一样
    • 我希望使用开关,因为我更喜欢它。 - 我已经添加了我当前的代码,请看一下。我应该在 setState 块中写什么?
    • 哦,您不必在其中放置任何东西...它会保留在那里,因此无论何时更改开关,都会使用新值重建 UI...如果您按原样删除它....您会注意到 UI 没有更新
    • 是的,到目前为止它正在工作,因为我能够保存开关的状态 - 但是现在我无法让它切换任何主题。不知何故,我需要在开关值字段中调用`toggleSwitch`函数,但它不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2021-01-26
    • 2021-03-31
    • 2019-02-12
    • 2020-06-02
    • 2021-06-30
    相关资源
    最近更新 更多