从父级更新警报模态子级
Update alert modal child from parent
我在按下按钮时调用显示我的对话框以显示父项中的上传进度。
在整个上传功能的部分中,我正在更新状态,例如 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)),
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')),
],
),
),
);
}
}
我在按下按钮时调用显示我的对话框以显示父项中的上传进度。
在整个上传功能的部分中,我正在更新状态,例如 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)),
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')),
],
),
),
);
}
}