如何使循环进度指示器工作

时间:2018-01-29 01:46:01

标签: dart flutter

更新 我已经改为使用一个小部件并将所有代码放在下面的Stateful Widget中。

这里有很多代码,我改为使用带有Widget loadingIndicator的堆栈,但它仍然没有被调用。我的堆栈是围绕未来的响应,指示器位于底部,然后我从按钮单击使用onPress来调用更改状态的方法,然后我调用另一个进程来运行。该指标仍未发生任何事情。

class ChatServerDivided extends StatefulWidget {
  ChatServerDivided({Key key, this.title, this.mychat}) : super(key: key);

  static const String routeName = "/ChatServerDivided";

  final ChatServerList mychat;
  final String title;

  @override
  _ChatServerDividedState createState() => new _ChatServerDividedState();
}

class _ChatServerDividedState extends State<ChatServerDivided> {
  SharedPreferences prefs;
  int oid = 0;
  int pid = 0;
  int authlevel = 0;
  bool admin = false;
  int type = 0;
  String msgid = '';
  List chatlist;
  int listcount = 0;
  bool grpmsg = true;
  String sender = '';
  String receiver = '';
  String message = '';
  String oname = '';
  String pname = '';
  String sendname;
  String receivename;
  String replyto = '';
  String replyfrom = '';
  String replysub = '';
  final TextEditingController _newreplycontroller = new TextEditingController();
  String myfcmtoken = 'NONE';
  static ScrollController _scrollController;
  bool messSync = false;

  //Future<http.Response> _responseFuture;
  Future<List<Map>> _responseFuture;
  var _urlDates = '';
  Future<File> _imageFile;
  String myimage;
  String myvideo;
  File myimagefile;
  File myvidfile;
  Future<int> myimagelength;
  String myext;
  VideoPlayerController vcontroller;
  bool isImage = false;
  bool isVideo = false;
  bool submitting = false;

  //ScrollController scontroller = new ScrollController();

  _getPrefs() async {
    prefs = await SharedPreferences.getInstance();

    if (mounted) {
      setState(() {
        oid = prefs.getInt('oid');
        pid = prefs.getInt('pid');
        authlevel = prefs.getInt('authlevel');
        admin = prefs.getBool('admin');
        type = 1;
        msgid = widget.mychat.msgkey;
        if (widget.mychat.grpid == 0) {
          grpmsg = false;
        } else {
          grpmsg = true;
        }
        oname = widget.mychat.oname;
        pname = widget.mychat.pname;
        myfcmtoken = prefs.getString('fcmtoken');
        if (authlevel == 0) {
          sender = 'o';
          receiver = 'p';
          sendname = widget.mychat.oname;
          receivename = widget.mychat.pname;
        } else if (authlevel == 1) {
          sender = 'p';
          receiver = 'o';
          sendname = widget.mychat.pname;
          receivename = widget.mychat.oname;
        }
        //_getChats();
      });
    }
  }

  @override
  void initState() {
    super.initState();
    //controller = new TabController(length: 4, vsync: this);

    _scrollController = new ScrollController();
    //_scrollController.position.maxScrollExtent;
    _getPrefs();
    _urlDates =
        'http://$baseurl/chat/messages/getdates/${widget
        .mychat.msgkey}';
    _responseFuture = ChatDB.instance.getMessagesDates(widget.mychat.msgkey);
  }

  @override
  void dispose() {
    super.dispose();
    if (vcontroller != null) {
      vcontroller.dispose();
    }

  }

  var jsonCodec = const JsonCodec();
  var _focusnode = new FocusNode();

  _getChats() async {
    var _url =
        'http://$baseurl/chat/messages/getdates/$msgid';

    var http = createHttpClient();
    var response = await http.get(_url, headers: getAuthHeader());

    var chats = await jsonCodec.decode(response.body);

    if (mounted) {
      setState(() {
        chatlist = chats.toList();
        listcount = chatlist.length;
        //replysub = 'Re: ' + chatlist[0]['sub'];
      });
    }
  }

  Future<Null> _onRefresh() {
    Completer<Null> completer = new Completer<Null>();
    Timer timer = new Timer(new Duration(seconds: 1), () {
      setState(() {
        _responseFuture =
            ChatDB.instance.getMessagesDates(widget.mychat.msgkey);
        print('RUNNING LOAD AFTER REFRESH AGAIN');
      });
      completer.complete();
    });
    return completer.future;
  }

  Future<String> doImageString() async {
    return (await _imageFile)
        .path
        .substring((await _imageFile).path.length - 3);
  }

  @override
  Widget build(BuildContext context) {
    _toggleProgress() {
      setState(() {
        submitting = true;
      });

    };
    Widget loadingIndicator =submitting? new Container(
      color: Colors.grey[300],
      width: 70.0,
      height: 70.0,
      child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
    ):new Container();
    Widget mytitle;
    if (grpmsg) {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.people),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    } else {
      mytitle = new Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Icon(Icons.person),
          new Text('  '),
          new Text(widget.mychat.referralname)
        ],
      );
    }

    var _children = <Widget>[
      new Flexible(
        child: new Stack(
          children: <Widget>[
            new FutureBuilder<List<Map>>(
              future: _responseFuture,
              builder:
                  (BuildContext context, AsyncSnapshot<List<Map>> snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                    return new Text('Waiting to start');
                  case ConnectionState.waiting:
                    return new Text('Loading...');
                  default:
                    if (snapshot.hasError) {
                      return new Text('Error: ${snapshot.error}');
                    } else {
                      return new RefreshIndicator(
                          child: new ListView.builder(
                            itemBuilder: (context, index) {
                              return new MyChatWidget(
                                datediv: snapshot.data[index]['msgdate'],
                                msgkey: snapshot.data[index]['msgkey'],
                              );

                            },
                            //itemBuilder: _itemBuilder,
                            controller: _scrollController,
                            reverse: true,
                            itemCount: snapshot.data.length,
                          ),
                          onRefresh: _onRefresh
                      );
                    }
                }
              },
            ),
            new Align(child: loadingIndicator,alignment: FractionalOffset.center,),
          ],
        ),
      ),

      new Container(
          alignment: Alignment.bottomLeft,
          padding: new EdgeInsets.only(left: 10.0),
          child: new FutureBuilder<File>(
              future: _imageFile,
              builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  //return new Image.file(snapshot.data);
                  myimagefile = snapshot.data;
                  myext = path.extension(myimagefile.path);
                  if (myext == '.jpg') {
                    isImage = true;
                    return new Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        new Container(
                          alignment: Alignment.bottomLeft,
                          width: 150.0,
                          child: new Image.file(snapshot.data),
                        ),
                        new FlatButton(
                            onPressed: _doClear,
                            child: new Text('Clear Image'))
                      ],
                    );
                  } else {
                    isVideo = true;
                    myvidfile = new File(
                        snapshot.data.path.replaceAll('file://', ''));
                    vcontroller = new VideoPlayerController(myimagefile.path)..initialize();
                    return new Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        new Container(
                          alignment: Alignment.bottomLeft,
                          width: 150.0,
                          child: new vplayer.VideoCard(
                            controller: vcontroller,
                            title: widget.mychat.referralname,
                            subtitle: 'Video',
                          ),
                        ),
                        new FlatButton(
                            onPressed: _doClear,
                            child: new Text('Clear Video'))
                      ],
                    );
                  }
                } else {
                  return const Text('');
                }
              })
      ),

      new Divider(
        height: 5.0,
        color: Colors.grey,
      ),
      new Row(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: <Widget>[
          new Container(
            alignment: Alignment.bottomLeft,
            //width: 50.0,
            child: new IconButton(
              icon: new Icon(Icons.add_a_photo),
              onPressed: _pickImage,
              alignment: Alignment.bottomLeft,
            ),
          ),
          new Flexible(
            child: new Container(
              alignment: Alignment.center,
              //width: 350.0,
              child: new TextField(
                decoration: const InputDecoration(
                  hintText: 'Reply',
                  labelText: 'Reply:',
                ),
                autofocus: false,
                focusNode: _focusnode,
                maxLines: 1,
                controller: _newreplycontroller,
                keyboardType: TextInputType.text,
              ),
            ),
          ),
          new Container(
              alignment: Alignment.bottomRight,
              //width: 50.0,
              child: new IconButton(
                icon: new Icon(Icons.send),
                onPressed: () {
                  _toggleProgress();
                  _sendReply();
                },
                alignment: Alignment.centerRight,
                disabledColor: Colors.grey,
              )),
        ],
      ),
    ];

    return new Scaffold(
      appBar: new AppBar(
        title: mytitle,
        actions: getAppBarActions(context),
      ),
      body: new Column(
        children: _children,
      ),
    );
  }

  DateTime getDateDiv(int index) {
    DateTime msgdate = DateTime.parse(chatlist[index]['chatdate']).toLocal();
    return msgdate;
  }

  _doClear() {
    setState(() {
      _imageFile = null;
    });
  }

  _pickImage() async {
    await setState(() {
      _imageFile = ImagePicker.pickImage(maxWidth: 600.0);
    });
  }

  _sendReply() {
    if (_newreplycontroller.text.isEmpty && myimagefile == null) {
      /*showDialog(
        context: context,
        child: new AlertDialog(
          content: new Text("There is no message to submit"),
          actions: <Widget>[
            new FlatButton(
                child: const Text('OK'),
                onPressed: () {
                  Navigator.pop(context, false);
                }),
          ],
        ),
      );*/
    } else {

      TextInputAction.done;
      DateTime dateSubmit = new DateTime.now();
      if (myimagefile != null) {
        if (isImage) {
          List<int> imageBytes = myimagefile.readAsBytesSync();
          myimage = BASE64.encode(imageBytes);
          myvideo = 'NONE';
        }
        if (isVideo) {
          List<int> imageBytes = myvidfile.readAsBytesSync();
          myvideo = BASE64.encode(imageBytes);
          myimage = 'NONE';
        }
      } else {
        myimage = 'NONE';
        myvideo = 'NONE';
      }
      var mymessage = _newreplycontroller.text;
      ChatServerMessage mychat = new ChatServerMessage(
          widget.mychat.msgkey,
          'message',
          widget.mychat.refid,
          widget.mychat.referralname,
          replysub,
          oid,
          oname,
          pid,
          pname,
          sender,
          sendname,
          receiver,
          receivename,
          mymessage,
          dateSubmit.toString(),
          widget.mychat.grpid.toString(),
          widget.mychat.prid.toString(),
          myfcmtoken,
          myimage,
          myvideo,
          myext);
      _doSendReply(mychat);
    }
  }


  _doSendReply(mychat) async {
    var json = jsonCodec.encode(mychat);
    ChatConnect.instance.sendmessage(json);
    _checkSync () {
      messSync = ChatConnect.instance.isSynced;
      if (messSync) {
        if (isImage) {
          Timer synctimer = new Timer(new Duration(seconds: 2), _checkSync);
        } else if (isVideo) {
          Timer synctimer = new Timer(new Duration(seconds: 5), _checkSync);
        } else {
          Timer synctimer = new Timer(new Duration(seconds: 2), _checkSync);
        }

      } else {
        setState(() {

          submitting = false;
          _onRefresh();
          _doClear();
          print('RUNNING LOAD AFTER SEND AGAIN');
        });
        _newreplycontroller.text = '';
        _focusnode.unfocus();
      }
    }
    _checkSync();

  }
}

2 个答案:

答案 0 :(得分:3)

我根据您上面的代码段创建了一个示例。黑色应用程序,带有一个按钮,可以使用setState()切换提交值。 点击FloatingActionButton调用setState,切换提交的值。并显示进度指示器。

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(home: new SubmitPage()));
}

class SubmitPage extends StatefulWidget {
  @override
  _SubmitPageState createState() => new _SubmitPageState();
}

class _SubmitPageState extends State<SubmitPage> {
  bool submitting = false;

  void toggleSubmitState() {
    setState(() {
      submitting = !submitting;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: !submitting
            ? new Container(
                color: Colors.grey,
              )
            : const Center(child: const CircularProgressIndicator()),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.refresh),
        onPressed: toggleSubmitState,
      ),
    );
  }
}

答案 1 :(得分:0)

您为什么不使用.gif图片呢?

只需将gif放在项目的图像文件夹中,并在pubspec.yaml文件中提及它,就像处理图像一样。

Image(
    image: AssetImage('images/circular-progress-bar.gif'),
    width: 40,
    height:40
 );