Я изучаю разработку приложений на Flutter и не могу заставить свой слайдер работать в AlertDialog. Это не изменит его значения.
Я поискал проблему и наткнулся на этот пост на StackOverFlow:
Flutter - Почему слайдер не обновляется в AlertDialog?
Я прочитал и вроде как понял. В принятом отвечать сказано, что:
The problem is, dialogs are not built inside build method. They are on a different widget tree. So when the dialog creator updates, the dialog won't.
Однако я не могу понять, как именно это должно быть реализовано, поскольку предоставляется недостаточно фонового кода.
Вот как выглядит моя текущая реализация:
double _fontSize = 1.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(qt.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.format_size),
onPressed: () {
getFontSize(context);
},
),
],
),
body: ListView.builder(
padding: EdgeInsets.symmetric(vertical: 15.0),
itemCount: 3,
itemBuilder: (context, index) {
if (index == 0) {
return _getListTile(qt.scripture, qt.reading);
} else if (index == 1) {
return _getListTile('Reflection:', qt.reflection);
} else {
return _getListTile('Prayer:', qt.prayer);
}
})
);
}
void getFontSize(BuildContext context) {
showDialog(context: context,builder: (context){
return AlertDialog(
title: Text("Font Size"),
content: Slider(
value: _fontSize,
min: 0,
max: 100,
divisions: 5,
onChanged: (value){
setState(() {
_fontSize = value;
});
},
),
actions: <Widget>[
RaisedButton(
child: Text("Done"),
onPressed: (){},
)
],
);
});
}
Widget parseLargeText(String text) {...}
Widget _getListTile(String title, String subtitle) {...}
Я понимаю, что мне нужно будет использовать async, await и Future. Но я не могу понять, как именно. Я потратил на эту проблему больше часа и больше не могу. Пожалуйста, простите меня, если этот вопрос глупый и глупый. Но поверьте, я старался изо всех сил.





Вот минимальный работоспособный пример. Ключевые моменты:
State. Это важно, потому что диалоги - это технически отдельные «страницы» в вашем приложении, вставленные выше в иерархии.Navigator.pop(...), чтобы закрыть диалог и вернуть результатasync / awaitimport 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
double _fontSize = 20.0;
void _showFontSizePickerDialog() async {
// <-- note the async keyword here
// this will contain the result from Navigator.pop(context, result)
final selectedFontSize = await showDialog<double>(
context: context,
builder: (context) => FontSizePickerDialog(initialFontSize: _fontSize),
);
// execution of this code continues when the dialog was closed (popped)
// note that the result can also be null, so check it
// (back button or pressed outside of the dialog)
if (selectedFontSize != null) {
setState(() {
_fontSize = selectedFontSize;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Font Size: ${_fontSize}'),
RaisedButton(
onPressed: _showFontSizePickerDialog,
child: Text('Select Font Size'),
)
],
),
),
);
}
}
// move the dialog into it's own stateful widget.
// It's completely independent from your page
// this is good practice
class FontSizePickerDialog extends StatefulWidget {
/// initial selection for the slider
final double initialFontSize;
const FontSizePickerDialog({Key key, this.initialFontSize}) : super(key: key);
@override
_FontSizePickerDialogState createState() => _FontSizePickerDialogState();
}
class _FontSizePickerDialogState extends State<FontSizePickerDialog> {
/// current selection of the slider
double _fontSize;
@override
void initState() {
super.initState();
_fontSize = widget.initialFontSize;
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Font Size'),
content: Container(
child: Slider(
value: _fontSize,
min: 10,
max: 100,
divisions: 9,
onChanged: (value) {
setState(() {
_fontSize = value;
});
},
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
// Use the second argument of Navigator.pop(...) to pass
// back a result to the page that opened the dialog
Navigator.pop(context, _fontSize);
},
child: Text('DONE'),
)
],
);
}
}
просто нужно деформировать AlertDialog () с помощью StatefulBuilder ()
На вопрос был дан ответ, ответ был одобрен и принят пользователем, который спросил, даже поблагодарил за ответ в комментарии. Обычно подобные вопросы не требуют дополнительных ответов.
Это именно то, что я искал. Огромное спасибо! Вы вернули мне уверенность, прося помощи в stackoverflow. Будьте здоровы!