简体   繁体   English

警报对话框中的值不会从外部更新

[英]values in alert dialog not update from outside

I need to show a progress bar like below:我需要显示如下进度条:

下载或上传进度条

I have implemented it this way but the value inside the progress bar is not updated:我是这样实现的,但是进度条内的值没有更新:

  1. use upload() function to simulate file upload by submitting a test POST request使用upload() function 提交测试POST请求模拟文件上传
  2. use StatefulBuilder() for convert my dialog from stateless to statefull使用StatefulBuilder()将我的对话框从无状态转换为有状态

my code:我的代码:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(const MaterialApp(
      home: MyApp(),
    ));

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String status = "loading ...";
  double uploadedPercent = 0.0;

  Future<void> upload() async {
    final response = await http.post(
      Uri.parse('https://jsonplaceholder.typicode.com/albums'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(<String, String>{
        'title': "test",
      }),
    );

    if (response.statusCode == 201) {
      // If the server did return a 201 CREATED response,
      // then parse the JSON.

      setState(() {
        status = "Uploaded";
        uploadedPercent = 1.0;
      });

      debugPrint(status);
    } else {
      throw Exception('Failed to create album.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Upload File'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                showDialog(
                  context: context,
                  builder: ((BuildContext context) {
                    return StatefulBuilder(builder: (context, setState) {
                      return AlertDialog(
                        title: Text(status),
                        content: LinearProgressIndicator(
                          value: uploadedPercent,
                          backgroundColor: Colors.grey,
                          color: Colors.green,
                          minHeight: 10,
                        ),
                      );
                    });
                  }),
                );
                upload();
              },
              child: const Text('Upload'),
            ),
          ],
        ),
      ),
      // buildFutureBuilder(),
    );
  }
}

my我的

status variable状态变量

and

uplaodPercent variable uplaodPercent变量

not be update in alert dialog and the my LinearProgressBar() stay in this state:不会在警报对话框中更新,我的LinearProgressBar()留在这个 state 中:

我的对话框

I conducted an experiment, its essence was to put the setState (() {});我做了一个实验,其实质就是把setState (() {}); method inside the StatefulBuilder and periodically call it to redraw the AlertBox widget, everything worked out for me, here is an example: StatefulBuilder 中的方法并定期调用它来重绘 AlertBox 小部件,一切都对我有用,这是一个例子:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: const Text("App bar"),
      ),
      body: HelpSO(count: 0.1),
    ));
  }
}

class HelpSO extends StatelessWidget {
  double count;

  HelpSO({Key? key, required this.count}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StatefulBuilder(builder:
        (BuildContext context, void Function(void Function()) setState) {
      Timer.periodic(const Duration(seconds: 2), (Timer t) {
        setState(() {
          count += 0.1;
          print(count);
        });
      });
      return AlertDialog(
        key: ValueKey(count),
        title: const Text("Loading..."),
        content: LinearProgressIndicator(
          value: count,
          backgroundColor: Colors.grey,
          color: Colors.green,
          minHeight: 10,
        ),
      );
    });
  }
}

在此处输入图像描述

So your problem is that everything works for you, but the widget is not redrawn, so try to put the setState(() {});所以你的问题是一切都适合你,但小部件没有重绘,所以试着把setState(() {}); in StatefulBuilder and call it at the moment when your widget needs to be updated.在 StatefulBuilder 中,并在您的小部件需要更新时调用它。

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

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