Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。
效果图:
实现代码:
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/9/23 22:51 * Description : 联系人 */ class MainContacts extends StatefulWidget { const MainContacts({super.key}); @override _WnChatHomePageState createState() => _WnChatHomePageState(); } class _WnChatHomePageState extends State<MainContacts> with AutomaticKeepAliveClientMixin{ //必须要实现wantKeepAlive方法,否则点击底部按钮, 会出现重新初始化initState方法 @override bool get wantKeepAlive => true; ScrollController _scrollController = ScrollController(); //listview 的控制器 List<ContactsBeanComb> _contactList = []; bool isLoading = false; String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT); var baseEvent; @override void initState() { super.initState(); _initEvent(); _getData(); } @override void dispose() { super.dispose(); eventBus.off(baseEvent); } void _initEvent(){ baseEvent = eventBus.on<BaseEvent>((baseBean) { if(baseEvent != null && (baseBean.type == BaseEvent.TYPE_ADD_FRIENDS || baseBean.type == BaseEvent.TYPE_READ_FRIENDS)){ //接收添加好友 _refreshNewFriends(); } else if(baseEvent != null && (baseBean.type == BaseEvent.TYPE_RECEIVE_FRIENDS)){ //同意好友请求 _getData(); } }); } //新朋友格式 int newFriendsCount = 0; //刷新新朋友个数 void _refreshNewFriends() async { Timer(Duration(milliseconds: 1000),() => { _refreshNewFriendsDelay() }); } //刷新新朋友个数-等待1秒显示 void _refreshNewFriendsDelay() async { newFriendsCount = await ContactsRepository.getInstance().findAllContactsCombNewCount()??0; setState(() { }); } //加载数据 _getData() async { _refreshNewFriends(); List<ContactsBeanComb> contactList = await ContactsRepository.getInstance().findAllContactsComb(account); setState(() { _contactList = contactList; }); } //删除联系人 _deleteContacts(ContactsBeanComb contactsBeanComb) async{ String fromAccount = contactsBeanComb.fromAccount; String toAccount = contactsBeanComb.toAccount; LogUtils.d("删除账号:${fromAccount} , ${toAccount}"); String resultAccount = ""; String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT); if(account == fromAccount){ resultAccount = toAccount; } else { resultAccount = fromAccount; } //删除好友的同时,也把相关的聊天信息删除 ChatRepository.getInstance().deleteChatByFromToAccount(fromAccount, toAccount); //删除服务器的数据 ContactsRepository.getInstance().deleteContactsByAccountServer(fromAccount, toAccount); //删除本地联系人 bool deleteFlag = await ContactsRepository.getInstance().deleteContactsByAccount(fromAccount, toAccount); ChatSendBean chatSendBean = ChatSendBean(); chatSendBean.contentType = CommonUtils.TYPE_DELETE_FRIENDS; chatSendBean.content = account; String message = jsonEncode(chatSendBean); LogUtils.d("删除发送:${resultAccount}"); XmppManager.getInstance().sendMyMessage(resultAccount, message); Map<String, Object> result = HashMap<String, Object>(); eventBus.emit(BaseEvent(BaseEvent.TYPE_UPDATE_CHAT_STATUS, result: result)); if(deleteFlag){ CommonToast.show(context, "删除成功!"); _getData(); } else { CommonToast.show(context, "删除失败!"); } } //点击查看好友详情 _goDetails(ContactsBeanComb contactsBean){ String toAccount = ""; if(account == contactsBean.fromAccount){ toAccount = contactsBean.toAccount; } else { toAccount = contactsBean.fromAccount; } Navigator.push(context,MaterialPageRoute(builder: (context)=>ContactsDetails(toChatId: toAccount))); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ addFriendsWidget(), groupWidget(), Expanded( child:ListView.builder( itemCount: _contactList.length, controller: _scrollController, itemBuilder: (context, index) { return InkWell( onLongPress: (){ _showDeleteDialog(_contactList[index]); }, onTap: (){ _goDetails(_contactList[index]); }, child: Container( decoration: BoxDecoration(border: Border(bottom:BorderSide(color: Color(0xffd9d9d9), width: 0.3))), padding: EdgeInsets.only(left: 14, top: 10, bottom: 10), child: Row( children: [ CommonAvatarView.showBaseImage(_contactList[index].avatar, 44, 44), SizedBox(width: 12,), Text(_contactList[index].nickName, maxLines: 1,style: TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold),), ], ), ), ); }) ), ], ), ); } //新的朋友 Widget addFriendsWidget(){ return InkWell( onTap: (){ Navigator.push(context,MaterialPageRoute(builder: (context)=> const NewFriends())); }, child: Container( width: double.infinity, decoration: const BoxDecoration(border: Border(bottom:BorderSide(color: Color(0xffd9d9d9), width: 0.3))), padding: const EdgeInsets.only(left: 10, top: 12, bottom: 6), child: Row( children: [ _getNewFriendsCountWidget(), const SizedBox(width: 12,), const Text("新的朋友", maxLines: 1,style: TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold),), ], ), ), ); } //群聊 Widget groupWidget(){ return InkWell( onTap: (){ Navigator.push(context,MaterialPageRoute(builder: (context)=> GroupMain())); }, child: Container( width: double.infinity, decoration: const BoxDecoration(border: Border(bottom:BorderSide(color: Color(0xffd9d9d9), width: 0.3))), padding: const EdgeInsets.only(left: 10, top: 12, bottom: 6), child: Row( children: [ Image.asset(CommonUtils.getBaseIconUrlPng("main_group_icon"), width: 50, height: 50,), const SizedBox(width: 12,), const Text("群聊", maxLines: 1,style: TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold),), ], ), ), ); } //新朋友个数提示 Widget _getNewFriendsCountWidget(){ if(newFriendsCount <= 0){ return Image.asset(CommonUtils.getBaseIconUrlPng("main_contacts_icon"), width: 50, height: 50,); } else { return Badge( animationType: BadgeAnimationType.scale, badgeContent: Text("${newFriendsCount}", style: TextStyle(color: Colors.white),), child: Image.asset(CommonUtils.getBaseIconUrlPng("main_contacts_icon"), width: 50, height: 50,), ); } } //删除好友对话框 Future<void> _showDeleteDialog(ContactsBeanComb contactsBeanComb) async { return showDialog<Null>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: Text('确定要删除该好友吗?', style: new TextStyle(fontSize: 17.0)), actions: <Widget>[ MaterialButton( child: Text('取消'), onPressed: (){ LogUtils.d("确定取消"); Navigator.of(context).pop(); }, ), MaterialButton( child: Text('确定'), onPressed: (){ LogUtils.d("确定删除"); Navigator.pop(context); _deleteContacts(contactsBeanComb); }, ) ], ); } ); } }