我做了一个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完整的widget代码
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 类下。
它看起来不会更新值,并且当尝试更改值时保持在相同位置。
问题是 Slider 中有 2 个必需参数
(onChanged, value)
,所以我应该更新这个或 UI 保持安静,看看应用程序如何运行的视频
我还在 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(),
)
最简单且最少的线路: 使用 StatefulBuilder 作为 AlertDialog 中内容的顶部小部件。
StatefulBuilder(
builder: (context, state) => CupertinoSlider(
value: brightness,
onChanged: (val) {
state(() {
brightness = val;
});
},
),
));
我在复选框中遇到了同样的问题,这就是我的解决方案,即使这不是最好的方法。 (见代码中的注释)
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
);
}
}
在返回时使用滑块创建一个有状态类,并且双精度值应在有状态类内声明,因此 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;
});
},
),
);
}
}
我面临这个问题,并且发现上述所有解决方案都对我没有帮助,所以我尝试解决它并且成功了 这是我的解决方案:
import 'package:flutter/material.dart';
class PopUpWidget extends StatefulWidget {
const PopUpWidget({super.key});
@override
State<PopUpWidget> createState() => _PopUpWidgetState();
}
class _PopUpWidgetState extends State<PopUpWidget> {
List<String> img = [
'assets/images/formImage/team_effort.png',
'assets/images/formImage/playing_golf.png',
'assets/images/formImage/phone.png',
'assets/images/formImage/confirm.png'
];
int value = 0;
@override
Widget build(BuildContext context) {
return Container(
child: StatefulBuilder(
builder: (context, state) => AlertDialog(
content: Wrap(
children: [
Column(
children: [
Container(
alignment: Alignment.topRight,
child: CloseButton(
color: Colors.black,
onPressed: () {
Navigator.pop(context, '');
},
),
),
Container(
child: Row(
children: [
Expanded(
flex: 1,
child: TextButton(
onPressed: () {
setState(() {
if (value > 0) {
value = value - 1;
}
});
},
child: Icon(Icons.arrow_back)),
),
Expanded(
child: Image.asset(img[value]),
flex: 2,
),
Expanded(
flex: 1,
child: TextButton(
onPressed: () {
setState(() {
if (value < 3) {
value = value + 1;
}
});
},
child: Icon(Icons.arrow_forward)),
),
],
))
],
),
],
),
surfaceTintColor: Colors.transparent,
backgroundColor: Colors.transparent,
),
));
}
}