首页 > 解决方案 > flutter - 如何在 rflutter_alert 对话框中显示 CircularProgressIndicator

问题描述

我有以下代码。当用户单击“保存”按钮时,将运行 Web 服务。服务运行时,如何在 rflutter_alert 对话框中显示 CircularProgressIndicator?如果 Web 服务失败,我希望警报对话框保持打开状态,以便他们可以重试。

谢谢,

保罗

Future<bool> saveRequest({context, int rId}) {
  String _reason = '';
  GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  TextEditingController reasonController = TextEditingController();

  TextStyle _style = TextStyle(
      fontFamily: 'Montserrat', fontSize: 18.0, fontWeight: FontWeight.normal);

  InputDecoration _textFormFieldDecoration({String hintText, double padding}) =>
      InputDecoration(
        //contentPadding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
        contentPadding: EdgeInsets.all(padding),
        isDense: true,
        hintText: hintText,
        hintStyle: TextStyle(color: kHintText),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.all(Radius.circular(5)),
        ),
      );

  return Alert(
    context: context,
    title: 'New Request',
    //desc: 'Reason',
    content: Form(
     key: _formKey,
     child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        SizedBox(height: 20.0),
        Text('Reason', textAlign: TextAlign.left, style: _style),
        SizedBox(height: 10.0),
        TextFormField(
          validator: (value) {
            if (value.isEmpty) {
              return "please enter reason";
            }
            return null;
          },
          onSaved: (value) {
            _reason = value;
          },
          decoration: _textFormFieldDecoration(
            hintText: 'reason for request',
            padding: 8.0,
          ),
          controller: reasonController,
        ),
        SizedBox(height: 10.0),
      ],
     ),
    ),
    buttons: [
      DialogButton(
        child:
            Text('Save', style: TextStyle(color: Colors.white, fontSize: 20)),
        color: kMainColor,
        onPressed: () async {
          if (_formKey.currentState.validate()) {
            _formKey.currentState.save();
            var saved = await doSaveRequest(pReason: _reason);
            Navigator.pop(context, false);
            if (saved.savedOK) {
              Navigator.of(context).pop();
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => UserRequests(
                    rId: rId,
                  ),
                ),
              );
            } else {
              Navigator.pop(context, false);
            }
          }
        },
      ),
      DialogButton(
        child:
            Text('Cancel', style: TextStyle(color: Colors.white, fontSize: 20)),
        color: kMainColor,
        onPressed: () {
          Navigator.pop(context, false);
        },
      ),
    ],
  ).show();
}

标签: flutter

解决方案


您可以在下面复制粘贴运行完整代码

Step 1: 下面的代码使用 3 秒延迟来模拟doSaveRequest()
Step 2: 你可以使用StreamBuilder<bool>and use _events.add(true);beforedoSaveRequest()来显示CircularProgressIndicator()
Step 3: back to Form screen with_events.add(false);

代码片段

Future<bool> doSaveRequest({String pReason}) async {
    await Future.delayed(const Duration(seconds: 3), () {});
    print("3 secs");
    return false;
  }

return Alert(
      context: context,
      title: 'New Request',
      //desc: 'Reason',
      content: StreamBuilder<bool>(
          initialData: false,
          stream: _events.stream,
          builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
            print(" ${snapshot.data.toString()}");
            return snapshot.data
                ? CircularProgressIndicator()
                : Form(
                    key: _formKey,  
    ...
    onPressed: () async {
                if (_formKey.currentState.validate()) {
                  ...
                  _events.add(true);

                  var saved = await doSaveRequest(pReason: _reason);
                  if (saved) {
                    Navigator.pop(context, false);
                  } else {
                    _events.add(false);
                  }     

工作演示

在此处输入图像描述

完整代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      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> {
  int _counter = 0;
  Color kMainColor = Colors.blue;
  Color kHintText = Colors.blue;
  StreamController<bool> _events;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  initState() {
    super.initState();
    _events = new StreamController<bool>();
  }

  Future<bool> doSaveRequest({String pReason}) async {
    await Future.delayed(const Duration(seconds: 3), () {});
    print("3 secs");
    return false;
  }

  Future<bool> saveRequest({context, int rId}) {
    String _reason = '';
    GlobalKey<FormState> _formKey = GlobalKey<FormState>();

    TextEditingController reasonController = TextEditingController();

    TextStyle _style = TextStyle(
        fontFamily: 'Montserrat',
        fontSize: 18.0,
        fontWeight: FontWeight.normal);

    InputDecoration _textFormFieldDecoration(
            {String hintText, double padding}) =>
        InputDecoration(
          //contentPadding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
          contentPadding: EdgeInsets.all(padding),
          isDense: true,
          hintText: hintText,
          hintStyle: TextStyle(color: kHintText),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
        );

    return Alert(
      context: context,
      title: 'New Request',
      //desc: 'Reason',
      content: StreamBuilder<bool>(
          initialData: false,
          stream: _events.stream,
          builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
            print(" ${snapshot.data.toString()}");
            return snapshot.data
                ? CircularProgressIndicator()
                : Form(
                    key: _formKey,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(height: 20.0),
                        Text('Reason',
                            textAlign: TextAlign.left, style: _style),
                        SizedBox(height: 10.0),
                        TextFormField(
                          validator: (value) {
                            if (value.isEmpty) {
                              return "please enter reason";
                            }
                            return null;
                          },
                          onSaved: (value) {
                            _reason = value;
                          },
                          decoration: _textFormFieldDecoration(
                            hintText: 'reason for request',
                            padding: 8.0,
                          ),
                          controller: reasonController,
                        ),
                        SizedBox(height: 10.0),
                      ],
                    ),
                  );
          }),
      buttons: [
        DialogButton(
          child:
              Text('Save', style: TextStyle(color: Colors.white, fontSize: 20)),
          color: kMainColor,
          onPressed: () async {
            if (_formKey.currentState.validate()) {
              _formKey.currentState.save();
              print(_reason);

              _events.add(true);

              var saved = await doSaveRequest(pReason: _reason);
              if (saved) {
                Navigator.pop(context, false);
              } else {
                _events.add(false);
              }
              /*if (saved.savedOK) {
                Navigator.of(context).pop();
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => UserRequests(
                      rId: rId,
                    ),
                  ),
                );
              } else {
                Navigator.pop(context, false);
              }*/
            }
          },
        ),
        DialogButton(
          child: Text('Cancel',
              style: TextStyle(color: Colors.white, fontSize: 20)),
          color: kMainColor,
          onPressed: () {
            Navigator.pop(context, false);
          },
        ),
      ],
    ).show();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              child: Text('Alert'),
              onPressed: () {
                saveRequest(context: context, rId: 123);
              },
            ),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

推荐阅读