Flutter-为什么滑块在AlertDialog中不更新?

时间:2018-07-10 17:25:35

标签: dart flutter flutter-layout

我正在执行AlertDialog,所以当我尝试将Slider小部件插入值声音状态时确实很陌生,并且如果Slider不在AlertDialog之外,则不会发生

new Slider(
  onChanged: (double value) {
    setState(() {
      sliderValue = value;
    });
  },
  label: 'Oi',
  divisions: 10,
  min: 0.0,
  max: 10.0,
  value: sliderValue,
)

AlertDialog的完整小部件代码

Future<Null> _showDialog() async {
  await showDialog<Null>(
      context: context,
      builder: (BuildContext context) {
        return new AlertDialog(
          title: const Text('Criar novo cartão'),
          actions: <Widget>[
            new FlatButton(onPressed: () {
              Navigator.of(context).pop(null);
            }, child: new Text('Hello'))
          ],
          content: new Container(
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                new Text('Deseja iniciar um novo cartão com quantos pedidos ja marcados?'),
                new Slider(
              onChanged: (double value) {
                setState(() {
                  sliderValue = value;
                });
              },
              label: 'Oi',
              divisions: 10,
              min: 0.0,
              max: 10.0,
              value: sliderValue,
            )
              ],
            ),
          ),
        );
      }
  );
}

,所有内容都在StatefullWidget的State类下。

它看起来不会更新值,并且在尝试更改值时保持在同一位置。

更新1

问题是Slider (onChanged, value)中有2个必需的参数,因此我应该更新此参数或UI保持一致,请观看视频中应用程序的运行方式

Video on Youtube

更新2

我还打开了一个问题,可以在Github存储库中获得帮助,如果有人想获取更多信息,可以访问issue #19323

5 个答案:

答案 0 :(得分:7)

问题在于,掌握状态的不是您的对话框。名为showDialog的小部件。调用setState时(在对话框创建者上调用)也是如此。

问题在于,对话框不是在build方法中内置的。它们在不同的小部件树上。因此,当对话框创建者更新时,对话框不会。

相反,您应该使对话框保持状态。将数据保存在该对话框中。然后使用Navigator.pop(context, sliderValue)将滑块值发送回对话框创建者。

对话框中的等效项是

FlatButton(
  onPressed: () => Navigator.of(context).pop(sliderValue),
  child: Text("Hello"),
)

然后您可以了解showDialog结果的内部:

final sliderValue = await showDialog<double>(
  context: context,
  builder: (context) => MyDialog(),
)

答案 1 :(得分:1)

我想出了一个带有复选框的相同问题,即使不是最佳方法,这也是我的解决方案。 (请参见代码中的注释)

Future<Null>_showDialog() async {
  return showDialog < Null > (
    context: context,
    barrierDismissible: true,
    builder: (BuildContext context) {
      return new AlertDialog(
        title: Text("title"),
        content: Container(
          height: 150.0,
          child: Checkbox(
            value: globalSearch,
            onChanged: (bool b) {
              print(b);
              globalSearch = b;
              Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs
              _showDialog(); //here i call the same function
            },
          )),
      );
    },
  );
}

答案 2 :(得分:1)

我遇到了类似的问题,并通过将AlertDialog下的所有内容都放入StatefullWidget来解决。

    class <your dialog widget> extends StatefulWidget {
  @override
  _FilterDialogState createState() => _FilterDialogState();
}

class _<your dialog widget> extends State<FilterDialog> {

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      //your alert dialog content here
    );
  }
}

答案 3 :(得分:1)

最简单和最少的行数: 将StatefulBuilder用作AlertDialog中内容的顶部小部件。

states = {
'Alabama':'Montgomery',
'Alaska':'Juneau',
'Arizona':'Phoenix',
'Arkansas':'Little Rock',
'California':'Sacramento'
}

答案 4 :(得分:0)

在返回时使用滑块创建一个statefull类,并且double值应在statefull类内声明,以便setstate函数可以工作。

这是我为滑块弹出窗口执行的示例,它与警报对话框的用法相同,可以将变量声明为全局变量,因此可以由其他类访问

    class _PopupMenuState extends State<PopupMenu> {
      double _fontSize=15.0;
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Slider(
            value: _fontSize,
            min: 10,
            max: 100,
            onChanged: (value) {
              setState(() {
                print(value);
                _fontSize = value;
              });
            },
          ),
        );
      }
    }