颤动 - 为什么在AlertDialog中滑块不会更新?

Hel*_*ior 6 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,
)
Run Code Online (Sandbox Code Playgroud)

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,
            )
              ],
            ),
          ),
        );
      }
  );
}
Run Code Online (Sandbox Code Playgroud)

并且一切都在StatefullWidget的State类下.

它的外观不会更新值,当尝试更改值保持在相同位置时.

更新1

问题是Slider中有2个必需参数(onChanged, value),所以我应该更新这个或者UI保持相当,看视频如何运行aplication

Youtube上的视频

更新2

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

Rém*_*let 9

问题是你的对话框不是持有状态的.它是调用的小部件showDialog.当你打电话时setState,你正在打电话给对话创建者.

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

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

对话框中的等价物将是

FlatButton(
  onPressed: () => Navigator.of(context).pop(sliderValue),
  child: Text("Hello"),
)
Run Code Online (Sandbox Code Playgroud)

然后您可以在showDialog结果中捕获:

final sliderValue = await showDialog<double>(
  context: context,
  builder: (context) => MyDialog(),
)
Run Code Online (Sandbox Code Playgroud)


cmd*_*ter 6

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

                StatefulBuilder(
                  builder: (context, state) => CupertinoSlider(
                    value: brightness,
                    onChanged: (val) {
                      state(() {
                        brightness = val;
                      });
                    },
                  ),
                ));
Run Code Online (Sandbox Code Playgroud)


小智 5

我用复选框提出了同样的问题,这就是我的解决方案,即使这不是最好的方法。(见代码中的注释)

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
            },
          )),
      );
    },
  );
}
Run Code Online (Sandbox Code Playgroud)