简体   繁体   中英

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. i have used StatefulBuilder for it. 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();
    }
  }
  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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