SwitchListTile在对话框中未打开

时间:2020-05-21 10:12:08

标签: flutter

我正在尝试在对话框中创建可行的切换列表。带图标的开关,标题显示但未打开。

 Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: <Widget>[
              FlatButton.icon(
                icon: Icon(AntDesign.sound),
                label: Text('Sound Options'),
                onPressed: () {
                  setState(() {
                    showDialog(
                        context: context,
                        child: SimpleDialog(
                          children: <Widget>[
                            SimpleDialogOption(
                              child: SwitchListTile(
                                  title: Text('Mute'),
                                  secondary: Icon(AntDesign.sound),
                                  value: _mute,
                                  onChanged: (bool value) {
                                    setState(() {
                                      _mute = value;
                                    });
                                  }),
                            ),
                          ],
                        ));
                  });
                },
              )
            ],
          ),
        ),
      ),
    );
  }

1 个答案:

答案 0 :(得分:0)

setState重建您的生成方法并更改_mute值,但是SimpleDialog在另一个上下文中打开,因此该对话框不会重建。在其中更改值时,应使用AlertDialog和setState创建一个新的StatefulWidget

class Class1 extends StatefulWidget {
  @override
  _Class1State createState() => _Class1State();
}

class _Class1State extends State<Class1> {
  bool _mute = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: <Widget>[
              FlatButton.icon(
                icon: Icon(AntDesign.sound),
                label: Text('Sound Options'),
                onPressed: () {
                  showDialog(
                      context: context,
                      builder: (context) => MyDialog(_mute)
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}

class MyDialog extends StatefulWidget {
  bool mute;

  MyDialog(this.mute);

  @override
  _MyDialogState createState() => _MyDialogState();
}

class _MyDialogState extends State<MyDialog> {
  @override
  Widget build(BuildContext context) {
    return SimpleDialog(
      children: <Widget>[
        SimpleDialogOption(
          child: SwitchListTile(
            title: Text('Mute'),
            secondary: Icon(AntDesign.sound), 
            value: widget.mute,
            onChanged: (bool value) {
              setState(() {
                widget.mute = value;
              });
            }),
        ),
      ],
    );
  }
}

另外一些技巧,请使用builder而不是将showDialog与child一起使用,不赞成使用child,不要将整个SimpleDialog都包装在setState中,而应该只包装要更改的值,而包装对话框不会用新值重建。

来自文档

调用setState会通知框架内部状态 该对象的更改方式可能会影响用户界面 在此子树中,这将导致框架为 这个State对象。

您使用的setState重建整个Scaffold状态控件的子树,但是对话框在另一棵树中打开,它不属于该子树。如果您使用的是Android Studio,则会有一个抖动检查器(我相信Visual Studio可以也是如此),您可以在那里看到该对话框和您的StatefulWidget来自Material App(该对话框不是子树的一部分,因此不会重建)