更新 我已经改为使用一个小部件并将所有代码放在下面的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();
}
}
答案 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
);