Flutter - 为什么滑块在 AlertDialog 中不更新?
Flutter - Why slider doesn't update in AlertDialog?
我在做一个 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 的状态 class 下。
它看起来没有更新值,当尝试更改值时保持相同的位置。
更新 1
问题是 Slider (onChanged, value)
中有 2 个必需参数,所以我应该更新这个或者 UI 保持安静,看看视频如何应用 运行
更新 2
我还在 Github 存储库中打开了一个问题来获得帮助,如果有人想获得更多信息可以去 issue #19323
问题是保存状态的不是您的对话框。就是那个叫 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(),
)
我在复选框方面遇到了同样的问题,这就是我的解决方案,即使这不是最佳方法。 (见代码中的注释)
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
},
)),
);
},
);
}
我有类似的问题并通过将 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
);
}
}
最简单和最少的行数:
使用 StatefulBuilder 作为 AlertDialog 中内容的顶部小部件。
StatefulBuilder(
builder: (context, state) => CupertinoSlider(
value: brightness,
onChanged: (val) {
state(() {
brightness = val;
});
},
),
));
在 return 时间用滑块创建一个全状态 class 并且双精度值应该在全状态中声明 class 这样 setstate 函数就可以工作了。
这是我为我的滑块弹出窗口所做的一个示例,它与警报对话框的使用相同可以将变量声明为全局变量,因此其他 classes
可以访问它
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;
});
},
),
);
}
}
我在做一个 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 的状态 class 下。
它看起来没有更新值,当尝试更改值时保持相同的位置。
更新 1
问题是 Slider (onChanged, value)
中有 2 个必需参数,所以我应该更新这个或者 UI 保持安静,看看视频如何应用 运行
更新 2
我还在 Github 存储库中打开了一个问题来获得帮助,如果有人想获得更多信息可以去 issue #19323
问题是保存状态的不是您的对话框。就是那个叫 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(),
)
我在复选框方面遇到了同样的问题,这就是我的解决方案,即使这不是最佳方法。 (见代码中的注释)
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
},
)),
);
},
);
}
我有类似的问题并通过将 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
);
}
}
最简单和最少的行数: 使用 StatefulBuilder 作为 AlertDialog 中内容的顶部小部件。
StatefulBuilder(
builder: (context, state) => CupertinoSlider(
value: brightness,
onChanged: (val) {
state(() {
brightness = val;
});
},
),
));
在 return 时间用滑块创建一个全状态 class 并且双精度值应该在全状态中声明 class 这样 setstate 函数就可以工作了。
这是我为我的滑块弹出窗口所做的一个示例,它与警报对话框的使用相同可以将变量声明为全局变量,因此其他 classes
可以访问它 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;
});
},
),
);
}
}