简体   繁体   English

Flutter 根据某些条件在 showDialog 内部进行更改

[英]Flutter Make changes inside showDialog according to some condition

I want to show a dialog containing loading indicator and text while uploading some data to server.我想在将一些数据上传到服务器时显示一个包含加载指示器和文本的对话框。 And I want to change the loading indicator to success Icon when the data is uploaded.我想在上传数据时将加载指示器更改为成功图标。 Currently i am using a variable to store the state and using that I am trying to change the child widgets inside the dialog.目前我正在使用一个变量来存储状态并使用它来尝试更改对话框内的子小部件。 But this approach doesn't work.但这种方法行不通。 The child widgets does not change after data get uploaded.上传数据后,子小部件不会更改。 Can anyone say what is the error and suggest some solution.谁能说出错误是什么并提出一些解决方案。

here is my code,这是我的代码,

import 'package:flutter/material.dart';
import 'package:loading_indicator/loading_indicator.dart';

class UploadData extends StatefulWidget {
  const UploadData({Key? key}) : super(key: key);

  @override
  State<UploadData> createState() => _UploadDataState();
}

class _UploadDataState extends State<UploadData> {
  bool isUploaded = false;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        height: MediaQuery.of(context).size.height,
        child: Center(
          child: TextButton(
            child: Text('Upload Data'),
            onPressed: () {
              uploadData();
            },
          ),
        ),
      ),
    );
  }
  
  void uploadData() async {
    showDialog(
      context: context, 
      builder: (context) {
        return AlertDialog(
          content: Column(
            children: [
              Text(
                isUploaded
                  ? 'Uploaded'
                  : 'Uploading',
              ),
              Container(
                height: 70,
                width: 70,
                child: isUploaded
                  ? const Icon(Icons.cloud_done, color: Colors.green,)
                  : const LoadingIndicator(
                      indicatorType: Indicator.lineSpinFadeLoader,
                      colors: [
                      Colors.red,
                      Colors.blue,
                      Colors.purple,
                      Colors.green,
                      Colors.yellow
                      ],
                    ),
              )
            ],
          ),
        );
      }
    );
    // The following function will upload the data
    await functionToUploadData();

    // Now changing variable to true
    setState(() {
      isUploaded = true;
    });

    // wait for 1 second to show the Updated dialog to user(i.e, now the dialog will contain message 'Uploaded') 
    await Future.delayed(const Duration(seconds: 1), () {});

    // Again changing the variable to false so that it will show uploading while uploading some other data. 
    setState(() {
      isUploaded = false;
    });

    Navigator.of(context).pop();
  }
}

But here the Dialogue box is not updating to status 'Uploaded'.但是这里的对话框没有更新到“已上传”状态。

使用 Future Builder 来完成你的工作, https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

you can do this!你可以这样做!

import 'package:flutter/material.dart';
import 'package:loading_indicator/loading_indicator.dart';

class UploadData extends StatefulWidget {
  const UploadData({Key? key}) : super(key: key);

  @override
  State<UploadData> createState() => _UploadDataState();
}

class _UploadDataState extends State<UploadData> {
  bool isUploaded = false;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        height: MediaQuery.of(context).size.height,
        child: Center(
          child: TextButton(
            child: Text('Upload Data'),
            onPressed: () {
              uploadData();
            },
          ),
        ),
      ),
    );
  }

  void uploadData() async {
    StateSetter? stateSetter;
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            content: StatefulBuilder(
              builder: (context,stateSetter) {
                stateSetter = stateSetter;
                return Column(
                  children: [
                    Text(
                      isUploaded
                          ? 'Uploaded'
                          : 'Uploading',
                    ),
                    Container(
                      height: 70,
                      width: 70,
                      child: isUploaded
                          ? const Icon(Icons.cloud_done, color: Colors.green,)
                          : const LoadingIndicator(
                        indicatorType: Indicator.lineSpinFadeLoader,
                        colors: [
                          Colors.red,
                          Colors.blue,
                          Colors.purple,
                          Colors.green,
                          Colors.yellow
                        ],
                      ),
                    )
                  ],
                );
              }
            ),
          );
        }
    );
    // The following function will upload the data
    await functionToUploadData();

    // Now changing variable to true
    if (stateSetter != null) {
      stateSetter(() {
        isUploaded = true;
      });
    }  
    

    // wait for 1 second to show the Updated dialog to user(i.e, now the dialog will contain message 'Uploaded') 
    await Future.delayed(const Duration(seconds: 1), () {});

    // Again changing the variable to false so that it will show uploading while uploading some other data. 
    setState(() {
      isUploaded = false;
    });

    Navigator.of(context).pop();
  }
}

Hello i have updated you uploadData method as below please try below code.您好,我已经更新了您的uploadData方法,如下所示,请尝试以下代码。 i have used StatefulBuilder for it.我已经为此使用了StatefulBuilder so it will change view based on condition.所以它会根据条件改变视图。

void uploadData() async {
    showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(
            builder: (BuildContext context, void Function(void Function()) setState) {  
              return AlertDialog(
                content: Column(
                  children: [
                    Text(
                      isUploaded
                          ? 'Uploaded'
                          : 'Uploading',
                    ),
                    Container(
                      height: 70,
                      width: 70,
                      child: isUploaded
                          ? const Icon(Icons.cloud_done, color: Colors.green,)
                          : const LoadingIndicator(
                        indicatorType: Indicator.lineSpinFadeLoader,
                        colors: [
                          Colors.red,
                          Colors.blue,
                          Colors.purple,
                          Colors.green,
                          Colors.yellow
                        ],
                      ),
                    )
                  ],
                ),
              );
            },
          );
        }
    );
    // The following function will upload the data
    await functionToUploadData();

    // Now changing variable to true
    setState(() {
      isUploaded = true;
    });

    // wait for 1 second to show the Updated dialog to user(i.e, now the dialog will contain message 'Uploaded') 
    await Future.delayed(const Duration(seconds: 1), () {});

    // Again changing the variable to false so that it will show uploading while uploading some other data. 
    setState(() {
      isUploaded = false;
    });

    Navigator.of(context).pop();
  }

Let me know if you have any question如果您有任何问题,请告诉我

 import 'package:flutter/material.dart';
  import 'package:loading_indicator/loading_indicator.dart';
  
  class UploadData extends StatefulWidget {
    const UploadData({Key? key}) : super(key: key);
  
    @override
    State<UploadData> createState() => _UploadDataState();
  }
  
  class _UploadDataState extends State<UploadData> {
    bool isUploaded = false;
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(),
        body: Container(
          height: MediaQuery.of(context).size.height,
          child: Center(
            child: TextButton(
              child: Text('Upload Data'),
              onPressed: () {
                uploadData();
              },
            ),
          ),
        ),
      );
    }
  
    void uploadData() async {
      StateSetter? stateSetter;
      showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              content: StatefulBuilder(builder: (context, stateSetter) {
                stateSetter = stateSetter;
                return Column(
                  children: [
                    Text(
                      isUploaded ? 'Uploaded' : 'Uploading',
                    ),
                    Container(
                      height: 70,
                      width: 70,
                      child: isUploaded
                          ? const Icon(
                              Icons.cloud_done,
                              color: Colors.green,
                            )
                          : const LoadingIndicator(
                              indicatorType: Indicator.lineSpinFadeLoader,
                              colors: [
                                Colors.red,
                                Colors.blue,
                                Colors.purple,
                                Colors.green,
                                Colors.yellow
                              ],
                            ),
                    )
                  ],
                );
              }),
            );
          });
      // The following function will upload the data
      await functionToUploadData();
  
      // Now changing variable to true
      if (stateSetter != null) {
        stateSetter(() {
          isUploaded = true;
        });
      }
  
      // wait for 1 second to show the Updated dialog to user(i.e, now the dialog will contain message 'Uploaded')
      await Future.delayed(const Duration(seconds: 1), () {});
  
      // Again changing the variable to false so that it will show uploading while uploading some other data.
      setState(() {
        isUploaded = false;
      });
  
      Navigator.of(context).pop();
    }
  }
  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM