Flutter实战一Flutter聊天应用(十九)
在上一篇文章中,我们完成了聊天列表的用户界面与功能代码。在用户添加完会话后,聊天列表会增加对应的会话项,通过点击会话项,可以进入聊天屏幕。在这一篇文章中,我们主要是修改lib/chat_screen.dart
的代码,也就是最早的聊天屏幕。
首先打开lib/chat_screen.dart
,在ChatScreen
中添加五个参数,messages
是会话对应的消息列表,myName
和sheName
是会话双方的名称,myPhone
和shePhone
则是双方的手机号码,也是唯一标识符。我们需要这些参数来将发送的消息写入到双方的数据节点。
class ChatScreen extends StatefulWidget {ChatScreen({this.messages, this.myName, this.sheName, this.myPhone, this.shePhone});final String messages;final String myName;final String sheName;final String myPhone;final String shePhone;@overrideState createState() => new ChatScreenState(messages);
}
接下来在ChatScreenState
中添加两个数据库连接,chatsReference
连接会话列表,messagesReference
连接具体每一个会话中的信息。还有一个ScaffoldState
类型的GlobalKey
变量,是用来控制聊天屏幕的脚手架(Scaffold
)的状态,比如在底部显示提示信息。
class ChatScreenState extends State<ChatScreen> {ChatScreenState(this._messages);final String _messages;static final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();final TextEditingController _textController = new TextEditingController();final chatsReference = FirebaseDatabase.instance.reference().child('chats');final messagesReference = FirebaseDatabase.instance.reference().child('messages');bool _isComposing = false;//...
}
我们再修改一下ChatScreenState
中的_sendMessage
方法,会话的一方只要发送了一条消息,就会更新双方的聊天列表中,显示最新的消息内容与消息发送的时间。这里保存的最新时间,是聊天列表排序的依据,这样聊天列表就会以消息的更新时间排序。
class ChatScreenState extends State<ChatScreen> {//...void _sendMessage({String text, String imageUrl}) {String time = new DateTime.now().toString();messagesReference.child(_messages).push().set({'text': text,'imageUrl': imageUrl,'senderName': widget.myName,'timestamp': time});chatsReference.child('${widget.shePhone}/${widget.myPhone}/lastMessage').set(text);chatsReference.child('${widget.shePhone}/${widget.myPhone}/timestamp').set(time);chatsReference.child('${widget.myPhone}/${widget.shePhone}/lastMessage').set(text);chatsReference.child('${widget.myPhone}/${widget.shePhone}/timestamp').set(time);}//...
}
在聊天屏幕的右上方,我们需要增加一个弹出菜单,使用PopupMenuButton
控件,在标题栏右方增加一个按钮,点击即可弹出选项菜单,更多关于弹出菜单按钮的内容,可以查看《Flutter进阶—质感设计之弹出菜单》。当用户点击删除选项时,会话双方的activate
都将被设置成false
,表示这个会话已经无效。
class ChatScreenState extends State<ChatScreen> {//...@overrideWidget build(BuildContext context) {return new Scaffold(key: _scaffoldKey,appBar: new AppBar(title: new Text(widget.sheName),centerTitle: true,elevation: 1.0,actions: <Widget>[new PopupMenuButton<String>(onSelected: (String value) {if (value == "delete") {chatsReference.child('${widget.shePhone}/${widget.myPhone}/activate').set("false");chatsReference.child('${widget.myPhone}/${widget.shePhone}/activate').set("false");_scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text("删除成功!"),));}},itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[new PopupMenuItem<String>(value: "delete", child: new Text('删除会话')),])]),body: new Stack(children: <Widget>[//...]),);}
}
当会话已经被被设置为无效状态时,应用程序不会自动返回到聊天列表屏幕,因此当用户再次发送消息时,我们应该提示用户该会话已经被删除。修改一下ChatScreenState
中的_handleSubmitted
方法,在发送消息之前先判断当前会话是否有效,有效时调用_sendMessage
方法发送消息,无效则使用脚手架来显示提示信息。
class ChatScreenState extends State<ChatScreen> {//...Future _handleSubmitted(String text) async {chatsReference.child('${widget.myPhone}/${widget.shePhone}/activate').onValue.listen((Event event) {if (event.snapshot.value == "false") {_scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text("会话已经被删除了哦!"),));} else {if (text.trim() == "") return;_textController.clear();_isComposing = false;_sendMessage(text: text);}});}//...
}
关于聊天屏幕的更多样式修改,可以查看chat_screen.dart文件了解详情。现在我们打开group_chat_list_body.dart
文件,修改一下_GroupChatListBodyState
的build
方法,当会话为无效时,不显示该会话。
class _GroupChatListBodyState extends State<GroupChatListBody> {//...@overrideWidget build(BuildContext context) {return new FirebaseAnimatedList(//...itemBuilder: (BuildContext context, DataSnapshot snapshot,Animation<double> animation) {return new SizeTransition(sizeFactor: animation,child: snapshot.value["activate"] == "false"? null: new GroupChatListBodyItem(//...),);},);}
}
Flutter实战一Flutter聊天应用(十九)相关推荐
- Flutter实战一Flutter聊天应用(二十)
在上一篇文章<Flutter实战一Flutter聊天应用(十九)>中,我们完成了删除用户的逻辑,就是将会话的有效性设置为false就可以了.那么当会话的有效性为false时,用户再次添加该 ...
- Flutter实战一Flutter聊天应用(十六)
在上一篇文章<Flutter实战一Flutter聊天应用(十五)>中,我们完成了登陆屏幕.在用户登陆成功后,会在本地创建一个LandingInformation文件,以使应用程序在启动时可 ...
- Flutter实战一Flutter聊天应用(十五)
在上一篇文章<Flutter实战一Flutter聊天应用(十四)>中,我们完成了注册屏幕.为了保持应用程序入口只有一个,即登陆屏幕,用户注册完成之后会返回手机号码.密码到登陆屏幕,让用户点 ...
- Flutter实战一Flutter聊天应用(汇总)
纸聊 这个应用程序使用Google的Flutter移动框架开发,是一个实时聊天应用程序,为了能专注于APP设计,应用程序的服务端使用Googler的Firebase平台.程序程序的名称为纸聊,意为像传 ...
- Flutter实战一Flutter聊天应用(五)
我们的应用程序现在已经有了一个好看的UI,但是我们还没有一个后端.所以我们要买一个云服务器,然后再安装数据库?当然不是!我们可以使用Firebase平台作为后端,那么Firebase是什么呢? Fir ...
- Flutter实战一Flutter聊天应用(十八)
在上一篇文章中,我们完成了基本的添加聊天功能,但是还没有在聊天列表显示添加的新聊天,在这篇文章中我们将实现这个功能--在聊天列表中展示所有的聊天. 首先,我们在/lib目录下新建一个group_cha ...
- Flutter实战一Flutter聊天应用(十)
首先,我们要修复一下之前几篇文章中存在的缺陷.在发送超过两行的消息时,屏幕上显示的消息不会自动换行,会超出最大宽度.我们可以通过将Text包装在Container控件中,再添加一个width属性,使其 ...
- Flutter实战一Flutter聊天应用(九)
在这篇文章中,我们将允许用户在聊天消息中发送图像,从设备检索图像文件,并将文本和图像数据存储在Google云端存储Bucket中.由于我们使用Firebase云储存,应用程序将变得更加健壮和可扩展.它 ...
- Flutter实战一Flutter聊天应用(十四)
优化输入体验 在进行下一步之前,我们先优化一下注册的体验: 正在输入注册信息时,点击屏幕空白部分,清除当前文本输入框的焦点,同时收起键盘. 正在输入注册信息时,直接收起键盘,再点击空白部分,清除当前文 ...
最新文章
- TensorRT Samples: GoogleNet
- 学界 | 进化算法可以不再需要计算集群,开普敦大学的新方法用一块GPU也能刷新MNIST记录
- ubuntu部署java环境
- 中国二氧化碳激光器行业现状研究与可行性分析报告2022-2028年版
- redis出现过多command 慢查询slowlog出现command命令
- php: +1天, +3个月, strtotime(): +1 day, +3 month
- python中的map,feilter,和reduce函数
- Golang练习题(自己认为比较不错的)
- python安装完毕后,用pip安装,提示找不到ssl模块
- ElasticSearch7.2只能用localhost访问但不能用IP地址访问---ElasticSearch工作笔记027
- 数据工作-百度统计初体验
- UVa101 - The Blocks Problem
- 二级c语言笔试57,二级C语言笔试真题与答案.doc
- python3 爬取搜狗微信的文章
- flume中HDFS IO error
- instagram获取图片地址和视频地址
- 计算机软件工程国家标准汇编目录
- 《安富莱嵌入式周报》第210期:2021.04.26--2021.05.02
- OSChina 周五乱弹 —— 我想当个昏君
- Java小程序,编写一个迷你DVD租借系统(控制台输出)
热门文章
- OpenCV:图片的几何变换
- Python使用库读取数据
- 建设城市(city)(【CCF】NOI Online 能力测试2 入门组第三题 )
- [转]linux用户管理
- stm32 CRC-16校验代码,单片机ModBUS-CRC16校验
- Android studio无法创建类和接口问题解决办法。提示 Unable to parse template Class
- 内存读写函数实现进程间通信
- Flex的Tree全部展开收缩,ji展开选中单个节点
- java.lang.InstantiationException:
- java解析xml文件