从父级更新警报模式子级

问题描述

当按下按钮以显示父级中的上传进度时,我正在调用显示我的对话框。

上传功能的各个部分中,我正在更新状态,例如 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')),

工作演示

enter image description here

完整代码

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);
                },],);
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...