Flutter - Почему слайдер не обновляется в 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.
Похоже, это не обновляет значение, а при попытке изменить значение остается в том же положении.
Обновление 1
Проблема в том, что в Slider есть 2 обязательных параметра (onChanged, value)
, Так что я должен обновить это или UI держать довольно, посмотреть видео, как работает приложение
Обновление 2
Я также открыл проблему, чтобы получить помощь по этому вопросу в хранилище Github, если кто-то хочет получить больше информации, можете перейти к выпуску #19323
2 ответа
Проблема в том, что это не ваш диалог, который содержит состояние. Это виджет, который называется 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;
});
},
),
);
}
}