flutter3-chat:基于flutter3.x+dart3聊天实例|flutter3仿微信App界面

flutter3_wchat全新跨平台flutter3.0仿微信app聊天应用。

基于多端跨平台技术flutter3+dart3+materialUI+shared_preferences+easy_refresh全新研发的一款仿微信app应用聊天实战项目。实现发送文字emoj消息+gif动图、长按仿微信发送语音、图片预览、红包及朋友圈等功能。

在这里插入图片描述

使用技术

编码工具:vscode
技术框架:flutter3.16.5+dart3.2.3
UI组件库:material-design3
弹窗组件:showDialog/SimpleDialog/showModalBottomSheet/AlertDialog
图片预览:photo_view^0.14.0
缓存组件:shared_preferences^2.2.2
下拉组件:easy_refresh^3.3.4
toast提示框:toast^0.3.0
网址预览组件:url_launcher^6.2.4

在这里插入图片描述
在这里插入图片描述
flutter3开发的应用支持运行到 android/ios/macos/linux/windows/web 等多个平台。

在这里插入图片描述

项目结构

通过flutter create xxx命令创建项目,目录结构如下图:

在这里插入图片描述
导航栏采用全屏沉浸式,支持透明背景图。

在这里插入图片描述
在项目开发初期,大家需要自行配置flutter/dart开发环境SDK。
https://flutter.dev/
https://flutter.cn/
https://pub.flutter-io.cn/
https://www.dartcn.com/

如果使用vscode开发项目,可自行按住flutter/dart扩展。

在这里插入图片描述
通过flutter doctor来检查所需环境是否缺失。一切准备就绪接 下来就是愉快的开发了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
既然看到了这里,是不是感觉还不错~~😁

开发初期是在windows调试比较方便,也可以运行到web上。后期可以直接打包apk运行到手机上。
运行到桌面默认是1280大小,大家可以修改windows/runner/main.cpp文件里面窗口尺寸,适应手机端。

在这里插入图片描述

如果大家习惯在模拟器上面运行调试项目,下面列出了一些常见的模拟器及端口连接。

在这里插入图片描述
通过adb connect连接上模拟器之后,flutter devices查看当前连接设备,执行flutter run命令即可运行项目到指定的模拟器。

入口main.dart

/// flutter入口文件import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:toast/toast.dart';// 引入公共样式
import 'styles/index.dart';// 引入底部tabbar
import 'components/tabbar.dart';// 引入路由管理
import 'router/index.dart';// 错误模块
import '../views/error/index.dart';void main() {runApp(const MyApp());
}DateTime? lastPopTime;class MyApp extends StatelessWidget {const MyApp({ super.key });// 退出app提示Future<bool> appOnPopInvoked(didPop) async {if(lastPopTime == null || DateTime.now().difference(lastPopTime!) > const Duration(seconds: 2)) {lastPopTime = DateTime.now();Toast.show('再按一次退出应用');return false;}SystemNavigator.pop();return true;}@overrideWidget build(BuildContext context){ToastContext().init(context);return MaterialApp(title: 'Flutter Chat',debugShowCheckedModeBanner: false,theme: ThemeData(primaryColor: FStyle.primaryColor,useMaterial3: true,// windows桌面端字体粗细不一样fontFamily: Platform.isWindows ? 'Microsoft YaHei' : null,),// home: const FTabBar(),home: PopScope(// canPop: false,onPopInvoked: appOnPopInvoked,child: const FTabBar(),),// 初始路由// initialRoute: '/',// 自定义路由onGenerateRoute: onGenerateRoute,// 错误路由onUnknownRoute: (settings) {return MaterialPageRoute(builder: (context) => const Error());},);}
}

Flutter3圆角/渐变背景色

在这里插入图片描述
如上图:flutter实现文本框圆角及按钮圆角渐变色。

Container(height: 40.0,margin: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 30.0),decoration: BoxDecoration(color: Colors.white,border: Border.all(color: const Color(0xffdddddd)),borderRadius: BorderRadius.circular(15.0),),child: Row(children: [Expanded(child: TextField(keyboardType: TextInputType.phone,controller: fieldController,decoration: InputDecoration(hintText: '输入手机号',suffixIcon: Visibility(visible: authObj['tel'].isNotEmpty,child: InkWell(hoverColor: Colors.transparent,highlightColor: Colors.transparent,splashColor: Colors.transparent,onTap: handleClear,child: const Icon(Icons.clear, size: 16.0,),)),contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 12.0),border: const OutlineInputBorder(borderSide: BorderSide.none),),onChanged: (value) {setState(() {authObj['tel'] = value;});},),)],),
),

通过Container组件gradient实现渐变色。

Container(margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 30.0),decoration: BoxDecoration(borderRadius: BorderRadius.circular(15.0),// 自定义按钮渐变色gradient: const LinearGradient(begin: Alignment.topLeft,end: Alignment.bottomRight,colors: [Color(0xFF0091EA), Color(0xFF07C160)],)),child: SizedBox(width: double.infinity,height: 45.0,child: FilledButton(style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.transparent),shadowColor: MaterialStateProperty.all(Colors.transparent),shape: MaterialStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)))),onPressed: handleSubmit,child: const Text('登录', style: TextStyle(fontSize: 18.0),),),)
),

flutter3登录验证60s倒计时

在这里插入图片描述

Timer? timer;
String vcodeText = '获取验证码';
bool disabled = false;
int time = 60;// 60s倒计时
void handleVcode() {if(authObj['tel'] == '') {snackbar('手机号不能为空');}else if(!Utils.checkTel(authObj['tel'])) {snackbar('手机号格式不正确');}else {setState(() {disabled = true;});startTimer();}
}
startTimer() {timer = Timer.periodic(const Duration(seconds: 1), (timer) {setState(() {if(time > 0) {vcodeText = '获取验证码(${time--})';}else {vcodeText = '获取验证码';time = 60;disabled = false;timer.cancel();}});});snackbar('短信验证码已发送,请注意查收', color: Colors.green);
}

Flutter3全屏沉浸导航状态栏渐变

在这里插入图片描述
由于AppBar提供的background属性不能设置渐变颜色,但是可以使用flexibleSpace属性 配合Container组件gradient实现导航栏渐变背景色。

AppBar(title: Text('Flutter3-Chat'),flexibleSpace: Container(decoration: const BoxDecoration(gradient: LinearGradient(begin: Alignment.topLeft,end: Alignment.bottomRight,colors: [Color(0xFF0091EA), Color(0xFF07C160)],)),)
),

flutter自定义badge红点/iconfont图标

在这里插入图片描述

FStyle.badge(23)
FStyle.badge(2, color: Colors.pink, height: 10.0, width: 10.0)
FStyle.badge(0, isdot: true)

自定义图标使用的阿里iconfont图表库。
在这里插入图片描述
在pubspec.yaml中引入字体文件。
在这里插入图片描述

class FStyle {// 自定义iconfont图标static iconfont(int codePoint, {double size = 16.0, Color? color}) {return Icon(IconData(codePoint, fontFamily: 'iconfont', matchTextDirection: true),size: size,color: color,);}// 自定义Badge红点static badge(int count, {Color color = Colors.redAccent,bool isdot = false,double height = 18.0,double width = 18.0}) {final num = count > 99 ? '99+' : count;return Container(alignment: Alignment.center,height: isdot ? height / 2 : height,width: isdot ? width / 2 : width,decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(100.00)),child: isdot ? null : Text('$num', style: const TextStyle(color: Colors.white, fontSize: 12.0)),);}
}

Flutter3仿微信快捷下拉菜单

在这里插入图片描述
通过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;}},
)// 下拉菜单项
static popupMenuItem(int codePoint, String title, value) {return PopupMenuItem(value: value,child: Row(mainAxisAlignment: MainAxisAlignment.start,children: [const SizedBox(width: 10.0,),FStyle.iconfont(codePoint, size: 21.0, color: Colors.white),const SizedBox(width: 10.0,),Text(title, style: const TextStyle(fontSize: 16.0, color: Colors.white),),],),);
}

flutter弹窗展示

项目中使用到了flutter各种弹窗应用场景。
在这里插入图片描述

// 关于弹窗
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实现微信群聊九宫格图像组

在这里插入图片描述
支持1-9张图片不同的排列组合。

const size = 44.0; // 默认一张图片尺寸
const padding = 2.0;
const margin = 2.0;int row = 0; // 图片行数
int col = 0; // 图片列数class GroupAvatar extends StatelessWidget {const GroupAvatar({super.key,this.avatars,});final List<String>? avatars;// 创建图片createImage(String avatar, double width) {return Image.asset(avatar,height: width,width: width,fit: BoxFit.fill,);}// 顶部一张图片avatarOne(List<Widget> stacks, Widget child, int count, i, imgWidth, left, top) {// ...}// 顶部两张图片avatarTwo(List<Widget> stacks, Widget child, int count, i, imgWidth, left, top) {// ...}// 其它情况avatarOther(List<Widget> stacks, Widget child, int count, i, imgWidth, left, top, colMax) {// ...}@overrideWidget build(BuildContext context){var count = avatars?.length;int colMax;List<Widget> icons = [];List<Widget> stacks = [];double imgWidth;if(count! == 1) {return SizedBox(width: size,height: size,child: createImage(avatars![0], size),);}if(count >= 5) {colMax = 3;imgWidth = (size - (padding * colMax) - margin) / colMax;}else {colMax = 2;imgWidth = (size - (padding * colMax) - margin) / colMax;}for(var i = 0; i < count; i++) {icons.add(createImage(avatars![i], imgWidth));}row = 0;col = 0;var centerTop = 0.0;if(count == 2 || count == 5 || count == 6) {centerTop = (imgWidth + margin) / 2;}for(var i = 0; i < count; i++) {var left = imgWidth * row + padding * (row + 1);var top = imgWidth * col + padding *  col + centerTop;switch(count) {case 3:case 7:avatarOne(stacks, icons[i], count, i, imgWidth, left, top);break;case 5:case 8:avatarTwo(stacks, icons[i], count, i, imgWidth, left, top);break;default:avatarOther(stacks, icons[i], count, i, imgWidth, left, top, colMax);break;}}return Container(width: size,height: size,color: const Color(0xFFEEEEEE),padding: const EdgeInsets.only(top: padding),child: Stack(children: stacks,),);}
}

flutter聊天功能模块

在这里插入图片描述

// 输入框
Offstage(offstage: voiceBtnEnable,child: TextField(decoration: const InputDecoration(isDense: true,hoverColor: Colors.transparent,contentPadding: EdgeInsets.all(8.0),border: OutlineInputBorder(borderSide: BorderSide.none),),style: const TextStyle(fontSize: 16.0,),maxLines: null,controller: editorController,focusNode: editorFocusNode,cursorColor: const Color(0xFF07C160),onChanged: (value) {},),
),

文本框支持文字/emoj输入,多行文本输入。输入链接,消息自动转换为网址通过浏览器打开。

在这里插入图片描述
仿微信按住说话语音面板模块。

// 语音
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绘制箭头,flutter提供了自定义绘图画板能力。

// 绘制气泡箭头
class ArrowShape extends CustomPainter {ArrowShape({required this.arrowColor,this.arrowSize = 7,});final Color arrowColor; // 箭头颜色final double arrowSize; // 箭头大小@overridevoid 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);}@overridebool shouldRepaint(CustomPainter oldDelegate) {return false;}
}

OK,综上就是flutter3/dart3开发跨平台聊天应用的一些知识分享。

最后附上两个最近的实例项目

  • 基于uni-app+vue3+pinia跨端仿抖音直播商城
    https://blog.csdn.net/yanxinyun1990/article/details/135329724

  • react18+electron27桌面端macos管理系统
    https://blog.csdn.net/yanxinyun1990/article/details/134567716

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/456099.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WAF防火墙到底有什么作用

引文 在当今数字化时代&#xff0c;网站安全威胁日益增加&#xff0c;作为网站业务的从业者&#xff0c;您必须确保您的网站在面对不断增长的网络威胁时可以保持绝对的安全。那么建立一个强大的多层防御体系至关重要。Web Application Firewall (WAF)作为防护体系中的重要一环…

【FPGA】高云FPGA之IP核的使用->PLL锁相环

FPGA开发流程 1、设计定义2、设计输入3、分析和综合4、功能仿真5、布局布线6、时序仿真7、IO分配以及配置文件&#xff08;bit流文件&#xff09;的生成8、配置&#xff08;烧录&#xff09;FPGA9、在线调试 1、设计定义 使用高云内置IP核实现多路不同时钟输出 输入时钟50M由晶…

2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题是由安全生产模拟考试一点通提供&#xff0c;危险化学品经营单位主要负责人证模拟考试题库是根据危险化学品经营单位主…

【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费

作者推荐 【动态规划】【状态压缩】【2次选择】【广度搜索】1494. 并行课程 II 本文涉及知识点 动态规划汇总 LeetCode1928. 规定时间内到达终点的最小花费 一个国家有 n 个城市&#xff0c;城市编号为 0 到 n - 1 &#xff0c;题目保证 所有城市 都由双向道路 连接在一起…

CleanMyMac X 4.14.7帮您安全清理Mac系统垃圾

CleanMyMac X 4.14.7是一款强大的 Mac 清理、加速工具和健康卫士,可以让您的 Mac 再次恢复巅峰性能。 移除大型和旧文件、卸载应用,并删除浪费磁盘空间的无用数据。 5倍 更多可用磁盘空间 CleanMyMac X 4.14.7帮您安全清理Mac系统垃圾 CleanMyMac X 4.14.7一键深度扫描mac系统…

使用GDI画图片生成合成图片并调用打印机进行图片打印

使用GDI画图片生成合成图片并调用打印机进行图片打印 新建窗体应用程序PrinterDemo&#xff0c;将默认的Form1重命名为FormPrinter&#xff0c;添加对 Newtonsoft.Json.dll用于读写Json字符串 zxing.dll&#xff0c;zxing.presentation.dll用于生成条形码&#xff0c;二维码…

ubuntu22.04 安装部署01:禁用内核更新

一、前言 ubunut22.04系统安装以后&#xff0c;内核更新会导致各种各样的问题&#xff0c;因此锁定初始安装环境特别重要&#xff0c;下面介绍如何锁定内核更新。 二、操作方法 2.1 查看可用内核 dpkg --list | grep linux-image dpkg --list | grep linux-headers dpkg --…

橘子学linux调优之工具包的安装

今天在公司无聊的弄服务器&#xff0c;想着有些常用的工具包安装一下&#xff0c;这里就简单记录一下。 一、sysstat的安装和使用 1、安装 我是通过源码的方式安装的&#xff0c;这样的好处在于可以自由选择你的版本&#xff0c;很直观。 直接去github上找到sysstat的地址&a…

这个门禁考勤技术,看了都说好!

在当今数字化时代&#xff0c;考勤管理对于企业、学校、机构等各类组织至关重要。随着科技的不断进步&#xff0c;传统的考勤方式逐渐显露出效率低、安全性差等问题。 因此&#xff0c;为了应对这些挑战&#xff0c;三维人脸考勤系统作为一项创新的解决方案应运而生。 客户案例…

力扣面试题 05.03. 翻转数位(前、后缀和)

Problem: 面试题 05.03. 翻转数位 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.将十进制数转换为二进制数&#xff08;每次按位与1求与&#xff0c;并且右移&#xff09;&#xff1b; 2.依次求取二进制数中每一位的前缀1的数量和&#xff0c;和后缀1的数量和…

Java设计模式-责任链模式

责任链模式 一、概述二、结构三、案例实现四、优缺点五、源码解析 一、概述 在现实生活中&#xff0c;常常会出现这样的事例&#xff1a;一个请求有多个对象可以处理&#xff0c;但每个对象的处理条件或权限不同。例如&#xff0c;公司员工请假&#xff0c;可批假的领导有部门…