I'm calling show my dialog when a button is pushed to display the progress of an upload which is in the parent.
Throughout the upload function's parts I'm updating state like setState(() => _progress = _progress + 0.05);
for example. However my dialog value is not correctly being updated as well. I think that the dialog is not rebuilding. How do I get the dialog to listen to this value and rebuild when it's updated?
Dialog code:
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.all(10.0),
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
height: MediaQuery.of(context).size.width * 0.3,
width: MediaQuery.of(context).size.width * 0.9,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Uploading...",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
SizedBox(height: 30),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: LinearProgressIndicator(
minHeight: 15,
value: _progress,
))
])),
);
}));
},
);
Trigger dialog code:
onPressed: () async {
setState(() => loading = true);
_showMyDialog();
await uploadAudio();
setState(() => loading = false);
},
You can copy paste run full code below
You can use ValueNotifier<double>
and ValueListenableBuilder
code snippet
final ValueNotifier<double> _progress = ValueNotifier<double>(0);
Future<void> uploadAudio() async {
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 0.1;
...
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 1.0;
}
Future<void> _showMyDialog() async {
...
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: ValueListenableBuilder(
builder: (BuildContext context, double value,
Widget child) {
return LinearProgressIndicator(
minHeight: 15, value: value);
},
valueListenable: _progress))
])),
);
}));
},
);
}
ElevatedButton(
onPressed: () async {
setState(() => loading = true);
_progress.value = 0;
_showMyDialog();
await uploadAudio();
setState(() => loading = false);
},
child: Text('Upload')),
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool loading;
final ValueNotifier<double> _progress = ValueNotifier<double>(0);
Future<void> uploadAudio() async {
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 0.1;
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 0.5;
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 0.7;
await Future.delayed(Duration(seconds: 2), () {});
_progress.value = 1.0;
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.all(10.0),
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
height: MediaQuery.of(context).size.width * 0.3,
width: MediaQuery.of(context).size.width * 0.9,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Uploading...",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
SizedBox(height: 30),
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: ValueListenableBuilder(
builder: (BuildContext context, double value,
Widget child) {
return LinearProgressIndicator(
minHeight: 15, value: value);
},
valueListenable: _progress))
])),
);
}));
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
setState(() => loading = true);
_progress.value = 0;
_showMyDialog();
await uploadAudio();
setState(() => loading = false);
},
child: Text('Upload')),
],
),
),
);
}
}