更改标签时如何保持拨动开关状态?

时间:2019-01-23 18:01:29

标签: dart flutter

我正在构建三页的警报(存储在不同列表中),这些警报已通过Scaffold和TabViewer显示。每个警报都通过一个拨动开关存储为一行以启用它。每个页面的行都存储为列表。尽管在更改值时甚至确保使用设置状态,甚至尝试分配唯一键,但我似乎都没有做任何事情来在更改选项卡时保留开关的状态。

这是我第一次使用Flutter / Dart进行编码,或者通常是为移动设备设计应用程序。因此,我仍在学习该语言的一些基本功能。

我尝试使用Uniquekey()向所有内容添加键以生成向上键不起作用,因此我将其删除。 我确保所有变量更改都在设置状态函数内部。 我试图将变量存储在AlarmToggle的不变超类中,该类既不明智,也无法正常工作。

我不厌倦使用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

无论我尝试尝试什么,每次更改选项卡时,AlarmRow()中的_alarmIsActive变量都会重置为null。我正在尝试在更改页面时保留其状态。

2 个答案:

答案 0 :(得分:0)

该解决方案就像jdv所说的使用 AutomaticKeepAliveClientMixin 一样,虽然不难使用,但我认为我会在搜索后加入我发现的指令,以防有人搜索并找到该指令而没有。无法像我一样自动地知道如何实现它。

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

它在状态类中实现了要保留的任何可修改变量。 “扩展”之后的“ with”添加了Mixin,这是一种类继承。最后,它要求您将'wantKeepAlive'设置为true,并且在不渲染小部件时它会进行编译并且状态不会丢失。

为什么有状态的小部件会在未渲染时丢失状态,这仍是我一直在寻找的问题。但至少我有解决方案。

答案 1 :(得分:0)

我希望这对@Ender有帮助!检查此代码,可以创建一个全局共享首选项并使用它,如下所示:-

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