问题描述
当按下按钮以显示父级中的上传进度时,我正在调用显示我的对话框。
在上传功能的各个部分中,我正在更新状态,例如 setState(() => _progress = _progress + 0.05);
。但是,我的对话框值也没有正确更新。我认为对话框没有重建。我如何让对话框听取这个值并在它更新时重建?
对话代码:
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,))
])),);
}));
},);
触发对话框代码:
onpressed: () async {
setState(() => loading = true);
_showMyDialog();
await uploadAudio();
setState(() => loading = false);
},
解决方法
您可以在下面复制粘贴运行完整代码
您可以使用 ValueNotifier<double>
和 ValueListenableBuilder
代码片段
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')),
工作演示
完整代码
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)),);
}
@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);
},],);
}
}