Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。
详情请查看
效果图:

详情请参考 Flutter高仿微信-第29篇-单聊 , 这里只是提取表情实现的部分代码。
实现代码:
//Emoji表情控件
Widget getEmojiWidget(){
return SizedBox(
height: 200.0,
width: 1000.0,
child: EmojiPicker(
onEmojiSelected: (Category category, Emoji emoji) {
_onEmojiSelected(emoji);
},
onBackspacePressed: _onBackspacePressed,
config: const Config(
columns: 7,
emojiSizeMax: 25.0,
verticalSpacing: 0,
horizontalSpacing: 0,
initCategory: Category.RECENT,
bgColor: Color(0xFFF2F2F2),
indicatorColor: Color(0xff65DAC5),
iconColor: Colors.orange,
iconColorSelected: Color(0xff65DAC5),
progressIndicatorColor: Color(0xff65DAC5),
backspaceColor: Color(0xff65DAC5),
showRecentsTab: true,
recentsLimit: 28,
categoryIcons: CategoryIcons(),
buttonMode: ButtonMode.MATERIAL)),
);
}
///选中表情
_onEmojiSelected(Emoji emoji) {
controller
..text += emoji.emoji
..selection = TextSelection.fromPosition(TextPosition(offset: controller.text.length));
hideAddIcon = true;
hideSend = false;
setState(() {
});
}
///表情删除按钮
_onBackspacePressed() {
controller
..text = controller.text.characters.skipLast(1).toString()
..selection = TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
if (controller.text.isNotEmpty) {
setState(() {
});
}
}
Emoji跟显示文本一样:
//我的文本
Widget meTextWidget(){
return Column(
// Column被Expanded包裹起来,使其内部文本可自动换行
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Color(0xFF9EEA6A),),
child: Text(
widget.chatBean.content??"",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
)
],
);
}
//朋友的文本
Widget toTextWidget(){
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 10.0),
decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5.0),),color: Color(0xFFEDEDED)),
child: Text(
widget.chatBean.content??"",
textAlign: TextAlign.left,
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
)
],
);
}
发送消息:
//定义发送表情事件的处理函数
void _handleSubmitted(String text) async {
if (text.length > 0) {
bool isNetwork = await CommonNetwork.isNetwork();
if(!isNetwork) {
CommonUtils.showNetworkError(context);
return;
}
bool deleteContacts = await isDeleteContacts(widget.account, widget.toChatId);
if(deleteContacts){
WnBaseDialog.showAddFriendsDialog(context, widget.toChatId);
return;
}
int contentType = CommonUtils.CHAT_CONTENT_TYPE_TEXT;
String addTime = WnDateUtils.getCurrentTime();
String messageId = UUID.getUUID();
ChatSendBean chatSendBean = ChatSendBean();
chatSendBean.contentType = contentType;
chatSendBean.content = text;
chatSendBean.addTime = addTime;
chatSendBean.second = 0;
chatSendBean.messageId = messageId;
String message = jsonEncode(chatSendBean);
_sendMessage(message);
controller.clear(); //清空输入框
ChatBean chatBean = ChatBean(fromAccount: widget.account, toAccount: widget.toChatId, content: text,contentType: contentType, addTime: addTime, isRead: 1, messageId: messageId);
LogUtils.d("插入数据:${chatBean.toJson()}");
//状态变更,向聊天记录中插入新记录
setState(() {
hideAddIcon = false;
hideSend = true;
items.add(chatBean);
});
await ChatRepository.getInstance().insertChat(chatBean);
jumpToBottom(100);
}
}
//发送消息
_sendMessage(var message){
int id = DateTime.now().millisecondsSinceEpoch;
String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT);
String toJid = "${widget.toChatId}@wangning";
XmppManager.getInstance().sendMessageWithType(toJid, message, "$account", id);
Map<String, Object> result = HashMap<String, Object>();
eventBus.emit(BaseEvent(BaseEvent.TYPE_NEW_MESSAGE, result: result));
}



















