简体   繁体   English

更改颤振选项卡时如何保持切换开关状态?

[英]How to perserve toggle switch state when changing tabs for flutter?

I'm building three pages of alarms (stored in different lists) that I have displayed via a Scaffold and TabViewer.我正在构建我通过 Scaffold 和 TabViewer 显示的三页警报(存储在不同的列表中)。 Each alarm is stored as a row with a toggle switch to enable it.每个警报都存储为一行,并带有一个切换开关以启用它。 The rows for each page are stored as a List.每个页面的行存储为一个列表。 Despite making sure to use set state when changing values and even trying to assign unique keys nothing I do seems to preserve the state of the switches when I changed tabs.尽管在更改值时确保使用 set state,甚至尝试分配唯一键,但我似乎没有在更改选项卡时保留开关的状态。

This is my first time coding in Flutter/Dart or designing an app for mobile in general.这是我第一次在 Flutter/Dart 中编码或设计移动应用程序。 As such I'm still learning about some basic features of this language.因此,我仍在学习这种语言的一些基本功能。

I've tried adding keys to everything using Uniquekey() to generate up keys didn't work so I've removed them.我尝试使用 Uniquekey() 向所有内容添加密钥以生成密钥不起作用,因此我已将其删除。 I've made sure all variable changes are inside set state functions.我已确保所有变量更改都在设置状态函数内。 I've tried to store the variable inside the immutable super class of AlarmToggle which is both ill-advised and doesn't work anyways.我试图将变量存储在 AlarmToggle 的不可变超类中,这既不明智又不起作用。

I haven't tired using PageStorageKey as I'm not sure how they'd be implemented in my code but I feel this is likely the only solution.我并没有厌倦使用 PageStorageKey,因为我不确定如何在我的代码中实现它们,但我觉得这可能是唯一的解决方案。

class Alarms {
  List<Widget> allAlarms = []; // Store all alarms for the object

  buildAlarm(
      GlobalKey<ScaffoldState>
          pageKey,
      [int hour,
      int minute,
      List<bool> alarmDaysOfWeek]) {

    TimeOfDay alarmTime = TimeOfDay(hour: hour, minute: minute);
    AlarmRow _newAlarm = new AlarmRow(UniqueKey(), alarmTime, alarmDaysOfWeek);
    allAlarms.add(_newAlarm);
  }
  void removeAlarm(GlobalKey<ScaffoldState> pageKey) {allAlarms.removeLast();}}

class AlarmRow extends StatefulWidget {
  final TimeOfDay _alarmTime;
  final List<bool> _alarmDaysofWeek;
  final UniqueKey key;
  AlarmRow(this.key, this._alarmTime, this._alarmDaysofWeek);
  AlarmRowState createState() => new AlarmRowState();
}

class AlarmRowState extends State<AlarmRow> {
  bool _alarmIsActive;

  AlarmRowState(){_alarmIsActive = _alarmIsActive ?? false;}

  void toggleChanged(bool state) {this.setState(() {_alarmIsActive = state;});}

  @override
  Widget build(BuildContext context) {
    return new Container(
      child: Row(
        children: <Widget>[
          new AlarmIcon(_alarmIsActive),
          new Column(
            children: <Widget>[
              new AlarmTime(widget._alarmTime),
              new AlarmWeekly(widget._alarmDaysofWeek),
            ],
          ),
          new AlarmToggle(
            _alarmIsActive,
            () => toggleChanged(!_alarmIsActive),
          ),
        ],
      ),
    );
  } // Build
} // Class

No matter what I seem to try the _alarmIsActive variable in AlarmRow() gets reset to null each time the tab is changed.无论我如何尝试,每次更改选项卡时,AlarmRow() 中的 _alarmIsActive 变量都会重置为 null。 I'm trying to preserve its state when changing pages.我试图在更改页面时保留其状态。

The solution is as jdv stated to use AutomaticKeepAliveClientMixin , it's not hard to use but I figured I'd include the instruction that I found after searching here in case anyone searches and finds this and doesn't know automatically how to implement it like myself.解决方案正如 jdv 所说的使用AutomaticKeepAliveClientMixin ,它不难使用,但我想我会在此处包含我在搜索后找到的说明,以防万一有人搜索并找到它并且不知道如何像我自己一样自动实现它。

class AlarmRowState extends State<AlarmRow> with AutomaticKeepAliveClientMixin {
    @override bool get wantKeepAlive => true;

It's implemented in the state class with any modifiable variables you want to preserve.它是在 state 类中实现的,带有您想要保留的任何可修改变量。 The 'with' after the 'extends' adds a Mixin which is a sort of class inheritance. 'extends' 后面的 'with' 添加了一个 Mixin,它是一种类继承。 Finally, it requires you to set the 'wantKeepAlive' to true and it compiles and state is no longer lost while the widget is not being rendered.最后,它要求您将 'wantKeepAlive' 设置为 true 并且它会编译并且在未呈现小部件时不再丢失状态。

Why a stateful widget loses state while it's not rendered is something I'm still searching for.为什么有状态小部件在未呈现时会丢失状态是我仍在寻找的东西。 But at least I have a solution.但至少我有一个解决方案。

I hope this will help you @Ender !我希望这会帮助你@Ender! check for this code, you can create a Global shared preference and use it, as shown below:-检查此代码,您可以创建一个全局共享首选项并使用它,如下所示:-

class AlarmRow extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => new _AlarmRowState();
}

class _AlarmRowState extends State<AlarmRow>{
  bool alarmIsActive;
  @override
  void initState() {
    alarmIsActive = Global.shared.alarmIsActive;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    ....
.....
....
....
      body: new Container(
        child:  Switch(
          value: alarmIsActive,
          onChanged: (bool isEnabled) {

            setState(() {
             alarmIsActive = isEnabled;
             Global.shared.alarmIsActive = isEnabled;
             isEnabled =!isEnabled;
            });
          },
         .....
......
        ),
      ),
    );
  }
}
class Global{
  static final shared =Global();
  bool alarmIsActive = false;
}

Switch enabled and will maintain its state开关已启用并将保持其状态

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM