最新版Flutter3.32+Dart3.8跨平台仿微信app聊天界面|朋友圈
2025原创研发flutter3+dart3实战仿微信App聊天系统Flutter3Chat。
flutter3_wechat:基于最新跨平台框架flutter3.32+dart3.8+get_storage+photo_view从0-1打造仿微信app聊天项目。包含聊天、通讯录、我的及朋友圈等模块。实现发送文字+emo表情消息、长按仿微信语音操作、图片/链接预览等功能。
最新研发flutter3.27+bitsdojo_window+getx客户端仿微信聊天Exe应用
Flutter3-MacOS桌面OS系统|flutter3.32+window_manager客户端OS模板
技术栈
- 编辑器:VScode
- 框架技术:Flutter3.32+Dart3.8
- 组件库:material-design3
- 弹窗组件:showDialog/SimpleDialog/showModalBottomSheet/AlertDialog
- 图片预览:photo_view^0.15.0
- 存储组件:get_storage^2.1.1
- 下拉刷新:easy_refresh^3.4.0
- toast提示:toast^0.3.0
- 网址预览组件:url_launcher^6.3.1
项目框架目录
flutter3-chat聊天app项目已经更新到我的原创作品集。
flutter3沉浸式渐变导航条
通过配置AppBar提供的可伸缩灵活区域属性 flexibleSpace 搭配gradient即可快速实现渐变导航栏。
AppBar( title: Text('Flutter3-Chat'), flexibleSpace: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFF0091EA), Color(0xFF07C160) ], ) ), ) ),
flutter3仿微信PopupMenu下拉菜单/下拉刷新
flutter提供的PopupMenuButton组件实现下拉菜单功能。
PopupMenuButton( icon: FStyle.iconfont(0xe62d, size: 17.0), offset: const Offset(0, 50.0), tooltip: '', color: const Color(0xFF353535), itemBuilder: (BuildContext context) { return <PopupMenuItem>[ popupMenuItem(0xe666, '发起群聊', 0), popupMenuItem(0xe75c, '添加朋友', 1), popupMenuItem(0xe603, '扫一扫', 2), popupMenuItem(0xe6ab, '收付款', 3), ]; }, onSelected: (value) { switch(value) { case 0: print('发起群聊'); break; case 1: Navigator.pushNamed(context, '/addfriends'); break; case 2: print('扫一扫'); break; case 3: print('收付款'); break; } }, )
下拉刷新、上拉加载更多是通过 easy_refresh 组件实现功能。
EasyRefresh( // 下拉加载提示 header: const ClassicHeader( // showMessage: false, ), // 加载更多提示 footer: ClassicFooter(), // 下拉刷新逻辑 onRefresh: () async { // ...下拉逻辑 await Future.delayed(const Duration(seconds: 2)); }, // 上拉加载逻辑 onLoad: () async { // ... }, child: ListView.builder( itemCount: chatList.length, itemBuilder: (context, index) { return Ink( // ... ); }, ), )
弹窗功能均是自定义AlertDialog实现效果。通过无限制容器UnconstrainedBox配合SizedBox组件实现自定义窗口大小。
// 关于弹窗 void aboutAlertDialog(BuildContext context) { showDialog( context: context, builder: (context) { return UnconstrainedBox( constrainedAxis: Axis.vertical, child: SizedBox( width: 320.0, child: AlertDialog( contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0), backgroundColor: Colors.white, surfaceTintColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), content: Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset('assets/images/logo.png', width: 90.0, height: 90.0, fit: BoxFit.cover,), const SizedBox(height: 10.0), const Text('Flutter3-WChat', style: TextStyle(color: Color(0xFF0091EA), fontSize: 22.0),), const SizedBox(height: 5.0), const Text('基于flutter3+dart3开发跨平台仿微信App聊天实例。', style: TextStyle(color: Colors.black45),), const SizedBox(height: 20.0), Text('©2024/01 Andy Q: 282310962', style: TextStyle(color: Colors.grey[400], fontSize: 12.0),), ], ), ), ), ), ); } ); } // 二维码名片弹窗 void qrcodeAlertDialog(BuildContext context) { showDialog( context: context, builder: (context) { return UnconstrainedBox( constrainedAxis: Axis.vertical, child: SizedBox( width: 320.0, child: AlertDialog( contentPadding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0), backgroundColor: const Color(0xFF07C160), surfaceTintColor: const Color(0xFF07C160), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3.0)), content: Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset('assets/images/qrcode.png', width: 250.0, fit: BoxFit.cover,), const SizedBox(height: 15.0), const Text('扫一扫,加我公众号', style: TextStyle(color: Colors.white60, fontSize: 14.0,),), ], ), ), ), ), ); } ); } // 退出登录弹窗 void logoutAlertDialog(BuildContext context) { showDialog( context: context, builder: (context) { return AlertDialog( content: const Text('确定要退出登录吗?', style: TextStyle(fontSize: 16.0),), backgroundColor: Colors.white, surfaceTintColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), elevation: 2.0, actionsPadding: const EdgeInsets.all(15.0), actions: [ TextButton( onPressed: () {Navigator.of(context).pop();}, child: const Text('取消', style: TextStyle(color: Colors.black54),) ), TextButton( onPressed: handleLogout, child: const Text('退出登录', style: TextStyle(color: Colors.red),) ), ], ); } ); }
flutter3实现微信朋友圈
ImageGroup(images: item['images']) ImageGroup( images: uploadList, album: true, onChoose: () async { Toast.show('选择手机相册图片', duration: 2, gravity: 1); }, )
/// 微信朋友圈九宫格图片 library; import 'package:flutter/material.dart'; import '../router/fade_route.dart'; import 'image_viewer.dart'; import '../utils/index.dart'; class ImageGroup extends StatelessWidget { const ImageGroup({ super.key, this.images, this.width = 200.0, this.album = false, this.limit = 9, this.onChoose, }); final List<String>? images; // 图片组 final double width; // 图片宽度 final bool album; // 是否相册/专辑(最后面显示+可选择图片) final int limit; // 限制多少张 final Function? onChoose; // 选择图片回调 int? get count => images?.length; List<String>? get imgList => count! >= limit ? images?.sublist(0, limit) : images; // 创建可点击预览图片 createImage(BuildContext context, String img, int key) { return GestureDetector( child: Hero( tag: 'image_${key}_$img', // 放大缩小动画效果标识 child: img == '+' ? Container(color: Colors.transparent, child: const Icon(Icons.add, size: 30.0, color: Colors.black45),) : Utils.isUrl(img) ? Image.network( img, width: width, fit: BoxFit.contain, ) : Image.asset( img, width: width, fit: BoxFit.contain, ), ), onTap: () { // 选择图片 if(img == '+') { onChoose!(); }else { Navigator.of(context).push(FadeRoute(route: ImageViewer( images: album ? imgList!.sublist(0, imgList!.length - 1) : imgList, index: key, heroTags: imgList!.asMap().entries.map((e) => 'image_${e.key}_${e.value}').toList(), ))); } }, ); } @override Widget build(BuildContext context){ // 一张图片 if(count == 1 && !album) { return SizedBox( width: width, child: createImage(context, imgList![0], 0), ); } if(album && count! < limit) { imgList?.add('+'); } // 多张图片 return GridView( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( // 横轴元素个数 crossAxisCount: 3, // 纵轴间距 mainAxisSpacing: 5.0, // 横轴间距 crossAxisSpacing: 5.0, // 子组件宽高比例 childAspectRatio: 1, ), children: imgList!.asMap().entries.map((e) { return Container( color: Colors.grey[100], child: createImage(context, e.value, e.key), ); }).toList(), ); } }
flutter3聊天功能
文本框TextField设置maxLines: null即可实现多行文本输入,支持图文emoj混排,网址连接识别等功能。
// 输入框 Offstage( offstage: voiceBtnEnable, child: ConstrainedBox( constraints: BoxConstraints(maxHeight: 300.0), child: TextField( decoration: InputDecoration( isDense: true, hoverColor: Colors.transparent, border: OutlineInputBorder(borderSide: BorderSide.none), contentPadding: EdgeInsets.fromLTRB(10, 0, 10, 0) ), style: const TextStyle(fontSize: 16.0,), maxLines: null, controller: editorController, focusNode: editorFocusNode, cursorColor: const Color(0xFF07C160), onChanged: (value) {}, ), ), )
// 语音 Offstage( offstage: !voiceBtnEnable, child: GestureDetector( child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), ), alignment: Alignment.center, height: 40.0, width: double.infinity, child: Text(voiceTypeMap[voiceType], style: const TextStyle(fontSize: 15.0),), ), onPanStart: (details) { setState(() { voiceType = 1; voicePanelEnable = true; }); }, onPanUpdate: (details) { Offset pos = details.globalPosition; double swipeY = MediaQuery.of(context).size.height - 120; double swipeX = MediaQuery.of(context).size.width / 2 + 50; setState(() { if(pos.dy >= swipeY) { voiceType = 1; // 松开发送 }else if (pos.dy < swipeY && pos.dx < swipeX) { voiceType = 2; // 左滑松开取消 }else if (pos.dy < swipeY && pos.dx >= swipeX) { voiceType = 3; // 右滑语音转文字 } }); }, onPanEnd: (details) { // print('停止录音'); setState(() { switch(voiceType) { case 1: Toast.show('发送录音文件', duration: 1, gravity: 1); voicePanelEnable = false; break; case 2: Toast.show('取消发送', duration: 1, gravity: 1); voicePanelEnable = false; break; case 3: Toast.show('语音转文字', duration: 1, gravity: 1); voicePanelEnable = true; voiceToTransfer = true; break; } voiceType = 0; }); }, ), )
flutter3绘制聊天箭头
// 绘制聊天箭头 class ArrowShape extends CustomPainter { ArrowShape({ required this.arrowColor, this.arrowSize = 7, }); final Color arrowColor; // 箭头颜色 final double arrowSize; // 箭头大小 @override void paint(Canvas canvas, Size size) { var paint = Paint()..color = arrowColor; var path = Path(); path.lineTo(-arrowSize, 0); path.lineTo(0, arrowSize); path.lineTo(arrowSize, 0); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } }
综上就是Flutter3+Dart3实战仿微信App聊天项目的一些知识分享,感谢大家的阅读与支持!
Flutter3-MacOS桌面OS系统|flutter3.32+window_manager客户端OS模板
附上几个最新项目实例
最新研发flutter3.27+bitsdojo_window+getx客户端仿微信聊天Exe应用
最新版uni-app+vue3+uv-ui跨三端仿微信app聊天应用【h5+小程序+app端】
最新版uniapp+vue3+uv-ui跨三端短视频+直播+聊天【H5+小程序+App端】
Uniapp-DeepSeek跨三端AI助手|uniapp+vue3+deepseek-v3流式ai聊天模板
Electron35-DeepSeek桌面端AI系统|vue3.5+electron+arco客户端ai模板
vue3-webseek网页版AI问答|Vite6+DeepSeek+Arco流式ai聊天打字效果
flutter3-dymall仿抖音直播商城|Flutter3.27短视频+直播+聊天App实例
tauri2.0-admin桌面端后台系统|Tauri2+Vite5+ElementPlus管理后台EXE程序
Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用