最新版Flutter3.32仿微信App聊天应用
基于最新版flutter3.32+dart3.8搭建跨平台仿微信app界面聊天|朋友圈实例项目Flutter3Chat,正式完结了!

flutter3-chat包含聊天、通讯录、我的及朋友圈等模块。实现发送文字+emo表情消息、长按仿微信语音操作、图片/链接预览等功能。

技术栈
- 开发工具:vscode
- 框架技术:flutter3.32+dart3.8
- 组件库:material-design3
- 图片预览: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聊天项目已经更新到我的原创作品集,感谢支持!https://b23.tv/6HWQ2xc




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

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;
}
},
)
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(),
);
}
}
最后附上该项目的链接,有需要的可以去看看。
https://b23.tv/6HWQ2xc
上一篇
利用DNS 枚举获取子域名
下一篇
开源、免费的MES系统
延伸阅读:
我为何放弃 frp,转向拥抱 WireGuard
相信绝大多数需要远程访问局域网服务的极客与我一样,最先接触的就是 frp,确实 frp 社区活跃、教程丰富并且其几乎被所...
破手机秒变服务器-Termux
手机玩 Linux 不是梦!你是否对 Android 的局限性感到无奈?你是否想在手机上运行强大的命令行工具、搭建服务器...
Typora 又一款AI加持的替代品 Zditor
在这个内容为王的时代,写作工具早已不只是“打字的地方”。它应该是创意的孵化器,是思维的延伸器,是效率的加速器。而 Zdi...
别再折腾FRP了!我用这个开源神器,让你无需公网IP,也能随时随地访问家里的任何设备
如果你跟我一样,手里有几台散落在不同地方的设备——比如家里的NAS、公司的开发机、自己随身的笔记本——那你肯定也折腾过怎...
这款 macOS 上超好用的翻译项目,高颜值、多功能,真太爽了!
作为一名程序员,我们每天都在跟英文打交道。市面上的翻译工具一抓一大把,网页版、APP、插件应有尽有,但对程序员来说,真正...