flutter3-dymall仿抖音直播商城|Flutter3.27短视频+直播+聊天App实例

news/2025/2/6 12:26:20/文章来源:https://www.cnblogs.com/xiaoyan2017/p/18700875

自研flutter3.27+dart3.6+getx实战抖音短视频+聊天+直播电商带货app商城应用。

flutter_dymall一款基于最新版Flutter3.27+Dart3.x+Getx+mediaKit原创实战研发抖音app带货商城项目。集成了直播+短视频+聊天三大功能模块。实现了类似抖音app首页全屏沉浸式联动左右滑动页面模块、上下滑动短视频效果。

使用技术

  • 编辑器:vscode
  • 技术框架:flutter3.27.1+Dart3.6.0
  • 路由/状态管理:get: ^4.6.6
  • 本地缓存服务:get_storage: ^2.1.1
  • 瀑布流组件:flutter_staggered_grid_view^0.7.0
  • 轮播图组件:card_swiper^3.0.1
  • toast弹窗组件:shirne_dialog^4.8.3
  • 视频套件:media_kit: ^1.1.11
  • svg图片:flutter_svg: ^2.0.16

附上两篇往期基于flutter3.x实战项目案例。

flutter3+dart3聊天室|Flutter3跨平台仿微信App语音聊天/朋友圈

flutter3-winchat桌面端聊天实例|Flutter3+Dart3+Getx仿微信Exe程序

实现了类似抖音app首页顶部状态栏+tab菜单栏+底部菜单栏联动效果,左右滑动切换页面,上下滑动切换短视频效果。

项目框架目录

目前flutter3_dymall直播app项目已经更新到我的原创作品集,有需要的可以去看看。

https://gf.bilibili.com/item/detail/1107796011

flutter3入口文件

/// 入口文件main.dart
library;import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:media_kit/media_kit.dart';
import 'package:shirne_dialog/shirne_dialog.dart';import 'utils/common.dart';// 引入布局页面
import 'layouts/index.dart';// 引入路由配置
import 'router/index.dart';void main() async {// 初始化get_storage存储
  await GetStorage.init();// 初始化media_kit视频套件
  WidgetsFlutterBinding.ensureInitialized();MediaKit.ensureInitialized();runApp(const App());
}class App extends StatelessWidget {const App({super.key});@overrideWidget build(BuildContext context) {return GetMaterialApp(title: 'Flutter3 DYMALL',debugShowCheckedModeBanner: false,theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFFFF9900)),useMaterial3: true,fontFamily: Platform.isWindows ? 'Microsoft YaHei' : null),home: const Layout(),// 初始化路由initialRoute: Common.isLogin() ? '/' : '/login',// 路由页面
      getPages: routePages,// 初始化弹窗key
      navigatorKey: MyDialog.navigatorKey,);}
}

flutter3沉浸式轮播图+tab吸附

如上图:轮播图延展到顶部状态栏,实现沉浸式效果。滚动页面tab栏固定吸附效果。

采用 CustomScrollView 滚动,搭配 SliverAppBar 实现顶部轮播图功能, SliverPersistentHeader 实现tab固定吸附效果。

return Scaffold(backgroundColor: Colors.grey[50],body: ScrollConfiguration(behavior: CustomScrollBehavior().copyWith(scrollbars: false),child: CustomScrollView(scrollBehavior: CustomScrollBehavior().copyWith(scrollbars: false),controller: scrollController,slivers: [SliverAppBar(backgroundColor: Colors.transparent,foregroundColor: Colors.white,pinned: true,expandedHeight: 200.0,titleSpacing: 10.0,// 搜索框(高斯模糊背景)
          title: ClipRRect(borderRadius: BorderRadius.circular(30.0),child: BackdropFilter(filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),child: Container(...),),),actions: [IconButton(icon: Icon(Icons.shopping_cart_outlined), onPressed: () {},),],// 自定义伸缩区域(轮播图)
          flexibleSpace: Container(decoration: BoxDecoration(gradient: LinearGradient(begin: Alignment.topLeft,end: Alignment.bottomRight,colors: [Color(0xFFFF5000), Color(0xFFfcaec4)])),child: FlexibleSpaceBar(background: Swiper.children(pagination: SwiperPagination(builder: DotSwiperPaginationBuilder(color: Colors.white70,activeColor: Colors.white,)),indicatorLayout: PageIndicatorLayout.SCALE,children: [Image.network('https://m.360buyimg.com/babel/jfs/t20271217/224114/35/38178/150060/6760d559Fd654f946/968c156726b6e822.png',),Image.network('https://m.360buyimg.com/babel/jfs/t20280117/88832/5/48468/139826/6789cbcfF4e0b2a3d/9dc54355b6f65c40.jpg',),Image.network('https://m.360buyimg.com/babel/jfs/t20280108/255505/29/10540/137372/677ddbc1F6cdbbed0/bc477fadedef22a8.jpg',),],),),),),...// tabbar列表
        SliverPersistentHeader(pinned: true,delegate: CustomStickyHeader(child: PreferredSize(preferredSize: Size.fromHeight(45.0),child: Container(...),),),),// 瀑布流列表
        ...],),),// 返回顶部
  floatingActionButton: Backtop(controller: scrollController, offset: scrollOffset),
);

flutter3实现底部联动tabbar

底部菜单栏依旧采用bottomNavigationBar实现切换页面模块。使用getx管理全局状态联动背景色。

中间菜单则是使用Positioned组件实现自定义功能。

@override
Widget build(BuildContext context) {return Scaffold(backgroundColor: Colors.grey[50],body: pageList[pageCurrent],// 底部导航栏
    bottomNavigationBar: Theme(data: ThemeData(splashColor: Colors.transparent,highlightColor: Colors.transparent,hoverColor: Colors.transparent,),child: Obx(() {return Stack(children: [Container(decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.black45, width: .1)),),child: BottomNavigationBar(backgroundColor: bottomNavigationBgcolor(),fixedColor: FStyle.primaryColor,unselectedItemColor: bottomNavigationItemcolor(),type: BottomNavigationBarType.fixed,elevation: 1.0,unselectedFontSize: 12.0,selectedFontSize: 12.0,currentIndex: pageCurrent,items: [...navItems],onTap: (index) {setState(() {pageCurrent = index;});},),),// 自定义导航栏中间按钮
            Positioned(left: MediaQuery.of(context).size.width / 2 - 18,top: 0,bottom: 0,child: InkWell(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Image.asset('assets/images/logo.png', width: 36.0, isAntiAlias: true, fit: BoxFit.contain,),],),onTap: () {setState(() {pageCurrent = 2;});},),),],);}),),);
}

flutter3实现抖音app首页联动tab效果

整个视频页分为顶部状态栏+导航栏Tab+内容区三部分。

实现左右滑动切换页面,上下滑动切换短视频联动效果。

@override
Widget build(BuildContext context) {return Scaffold(key: scaffoldKey,extendBodyBehindAppBar: true,appBar: AppBar(forceMaterialTransparency: true,backgroundColor: [0, 1, 4, 5].contains(videoModuleController.videoTabIndex.value) ? null : Colors.transparent,foregroundColor: [0, 1, 4, 5].contains(videoModuleController.videoTabIndex.value) ? Colors.black : Colors.white,titleSpacing: 1.0,leading: Obx(() => IconButton(icon: Badge.count(backgroundColor: Colors.red,count: 6,child: Icon(Icons.sort_rounded, color: tabColor(),),),onPressed: () {// 自定义打开右侧drawerscaffoldKey.currentState?.openDrawer();},)),title: Obx(() {return ScrollConfiguration(behavior: CustomScrollBehavior().copyWith(scrollbars: false),child: TabBar(...),);}),actions: [Obx(() => IconButton(icon: Icon(Icons.search_rounded, color: tabColor(),), onPressed: () {},),),],),body: ScrollConfiguration(behavior: CustomScrollBehavior().copyWith(scrollbars: false),child: PageView(controller: pageController,onPageChanged: (index) {videoModuleController.updateVideoTabIndex(index);setState(() {tabController.animateTo(index, duration: Duration(milliseconds: 200), curve: Curves.easeInOut);});},children: [...tabModules],),),// 侧边栏
    drawer: Drawer(shape: RoundedRectangleBorder(borderRadius: BorderRadius.horizontal(right: Radius.circular(15.0))),clipBehavior: Clip.antiAlias,width: 300,child: Container(...),),);
}

长列表滚动页面开启了缓存功能,滚动页面切换tab,页面滚动状态保持不变。

GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();VideoModuleController videoModuleController = Get.put(VideoModuleController());late TabController tabController = TabController(initialIndex: videoModuleController.videoTabIndex.value, length: tabList.length, vsync: this);
late PageController pageController = PageController(initialPage: videoModuleController.videoTabIndex.value, viewportFraction: 1.0);List<String> tabList = ['订阅', '逛逛', '直播', '团购', '短剧', '关注', '同城', '精选'];
final tabModules = [KeepAliveWrapper(child: SubscribeModule()),KeepAliveWrapper(child: BrowseModule()),KeepAliveWrapper(child: LiveModule()),KeepAliveWrapper(child: BuyingModule()),KeepAliveWrapper(child: DramaModule()),AttentionModule(),LocalModule(),RecommendModule()
];

class KeepAliveWrapper extends StatefulWidget {final Widget child;const KeepAliveWrapper({super.key, required this.child});@overrideState<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}class _KeepAliveWrapperState extends State<KeepAliveWrapper> with AutomaticKeepAliveClientMixin {@overrideWidget build(BuildContext context) {super.build(context);return widget.child;}@overridebool get wantKeepAlive => true;
}

flutter3短视频直播模块

底部播放进度条支持拖拽、点击,显示播放进度tip。

@override
Widget build(BuildContext context) {return Container(color: Colors.black,child: Column(children: [Expanded(child: Stack(children: [PageView.builder(scrollDirection: Axis.vertical,controller: pageController,onPageChanged: (index) async {// 更新播放索引
                  videoModuleController.updateVideoPlayIndex(index);setState(() {// 重置slider参数sliderValue = 0.0;sliderDraging = false;position = Duration.zero;duration = Duration.zero;});player.stop();await player.open(Media(videoList[index]['src']));},itemCount: videoList.length,itemBuilder: (context, index) {return Stack(children: [// 视频区域
                      Positioned(top: 0,left: 0,right: 0,bottom: 0,child: GestureDetector(child: Stack(children: [// 短视频插件
                              Visibility(visible: videoModuleController.videoPlayIndex.value == index && position > Duration.zero,child: Video(controller: videoController,fit: BoxFit.cover,),),// 播放/暂停按钮
                              StreamBuilder(stream: player.stream.playing,builder: (context, playing) {return Visibility(visible: playing.data == false,child: Center(child: IconButton(padding: EdgeInsets.zero,onPressed: () {player.playOrPause();},icon: Icon(playing.data == true ? Icons.pause : Icons.play_arrow_rounded,color: Colors.white60,size: 80,),style: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.black.withAlpha(15))),),),);},),],),onTap: () {player.playOrPause();},),),// 右侧操作栏
                      Positioned(bottom: 15.0,right: 6.0,child: Column(spacing: 15.0,children: [...],),),// 底部信息区域
                      Positioned(bottom: 15.0,left: 10.0,right: 80.0,child: Column(...),),// mini播放进度条
                      Positioned(bottom: 0.0,left: 6.0,right: 6.0,child: Visibility(visible: videoModuleController.videoPlayIndex.value == index && position > Duration.zero,child: Listener(child: SliderTheme(data: SliderThemeData(trackHeight: sliderDraging ? 6.0 : 2.0,thumbShape: RoundSliderThumbShape(enabledThumbRadius: 4.0), // 调整滑块的大小overlayShape: RoundSliderOverlayShape(overlayRadius: 0), // 去掉Slider默认上下边距间隙inactiveTrackColor: Colors.white24, // 设置非活动进度条的颜色activeTrackColor: Colors.white, // 设置活动进度条的颜色thumbColor: Colors.white, // 设置滑块的颜色overlayColor: Colors.transparent, // 设置滑块覆盖层的颜色
                              ),child: Slider(value: sliderValue,onChanged: (value) async {// debugPrint('当前视频播放时间$value');
                                  setState(() {sliderValue = value;});// 跳转播放时间await player.seek(duration * value.clamp(0.0, 1.0));},onChangeEnd: (value) async {setState(() {sliderDraging = false;});// 继续播放if(!player.state.playing) {await player.play();}},),),onPointerMove: (e) {setState(() {sliderDraging = true;});},),),),// 播放位置指示器
                      Positioned(bottom: 100.0,left: 10.0,right: 10.0,child: Visibility(visible: sliderDraging,child: DefaultTextStyle(style: TextStyle(color: Colors.white54, fontSize: 18.0, fontFamily: 'Arial'),child: Row(mainAxisAlignment: MainAxisAlignment.center,spacing: 8.0,children: [Text(position.label(reference: duration), style: TextStyle(color: Colors.white)),Text('/', style: TextStyle(fontSize: 14.0)),Text(duration.label(reference: duration)),],),)),),],);},),/// 固定层// 红包广告
              Ads(),],),),],),);
}

直播模块包含了顶部信息、直播礼物左侧滑入、进场动效右侧滑入、弹幕消息、右侧讲解商品、底部操作栏等功能。

// flutter3直播模块核心布局  Q:282310962

@override
Widget build(BuildContext context) {return Scaffold(backgroundColor: Colors.black,extendBodyBehindAppBar: true,appBar: AppBar(forceMaterialTransparency: true,backgroundColor: Colors.black,foregroundColor: Colors.white,toolbarHeight: 0,),body: Column(children: [Expanded(child: Stack(children: [PageView.builder(scrollBehavior: CustomScrollBehavior().copyWith(scrollbars: false),scrollDirection: Axis.vertical,controller: pageVerticalController,onPageChanged: (index) async {setState(() {liveIndex = index;});player.stop();await player.open(Media(liveJson[index]['src']));},itemCount: liveJson.length,itemBuilder: (context, index) {return Stack(children: [// 视频区域
                      Positioned(...),/// 水平滚动模块(清屏/浮层)
                      PageView(scrollDirection: Axis.horizontal,controller: pageHorizontalController,onPageChanged: (index) {// ...
                        },children: [// 直播清屏
                          Container(...),// 直播浮层
                          Stack(children: [// 顶部区域
                              Positioned(top: MediaQuery.of(context).padding.top + 7,left: 10.0,right: 0,child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 直播间头像
                                    Container(...),// 排名统计
                                    Container(...),// 红包活动
                                    Container(...),],),),// 底部区域
                              Positioned(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 商品购买动效
                                    Container(...),// 送礼物动效
                                    AnimationLiveGift(giftQueryList: [{'label': '小心心', 'gift': 'assets/images/gift/gift1.png', 'user': 'Jack', 'avatar': 'assets/images/avatar/img02.jpg', 'num': 12},{'label': '棒棒糖', 'gift': 'assets/images/gift/gift2.png', 'user': 'Andy', 'avatar': 'assets/images/avatar/img06.jpg', 'num': 36},{'label': '大啤酒', 'gift': 'assets/images/gift/gift3.png', 'user': '一条咸鱼', 'avatar': 'assets/images/avatar/img01.jpg', 'num': 162},...],),// 加入直播间动效
                                    AnimationLiveJoin(joinQueryList: [{'avatar': 'assets/images/logo.png', 'name': 'andy'},{'avatar': 'assets/images/logo.png', 'name': 'jack'},...],),// 直播弹幕+商品讲解
                                    Container(margin: EdgeInsets.only(top: 7.0),height: 200.0,child: Row(...),),// 底部工具栏
                                    Container(margin: const EdgeInsets.only(top: 7.0),child: Row(...),),],),),],),],),],);},),],),),],),);
}

以上就是flutter3.27实战开发抖音app商城的一些知识分享,整个项目涉及到的知识点还是非常多的,限于篇幅就暂时分享到这里,希望以上分享对大家有些许帮助~

附上几个最新跨平台实战项目案例。

Tauri2.0-Vue3OS桌面端os平台|tauri2+vite6+arco电脑版OS管理系统

uniapp+vue3酒店预订|vite5+uniapp预约订房系统模板(h5+小程序+App端)

Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用

Electron31-Vue3Admin管理系统|vite5+electron+pinia桌面端后台Exe

Vite5+Electron聊天室|electron31跨平台仿微信EXE客户端|vue3聊天程序

uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈

flutter3-winchat桌面端聊天实例|Flutter3+Dart3+Getx仿微信Exe程序

Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板

 

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

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

相关文章

DeepSeek-R1本地部署使用

春节期间突然被DeepSeek刷屏了,这宣传力度是真大,到处都是新闻和本地部署的教程,等热度过了过,简单记录下自己本地部署及相关的内容,就当电子宠物,没事喂一喂:D,不过有能力的还是阅读论文和部署完整版的进一步使用。 论文链接: https://github.com/deepseek-ai/DeepSee…

面向 Workload 级别的灵活可配置 Serverless 弹性解决方案

本文介绍的四种组件,在解决上述问题,具有各自的优势场景。用户可以根据自身实际场景选择合适的能力来用好弹性算力。Serverless 是云计算的进一步延伸,因此其继承了云计算的最大特点,即按需弹性伸缩。这样的模型设计让开发者无需关注具体的部署资源,充分利用资源规模效应,…

腾讯云 TI 平台部署与调用DeepSeek-R1大模型的实战指南

今天我们将继续探讨如何部署一个私有化的 DeepSeek-R1 大模型,具体的部署过程我们将利用腾讯云的 TI 平台进行操作。当前,腾讯云 TI 平台为用户提供了免费体验的满血版 DeepSeek-R1 大模型,同时该平台还提供了开放的 API 接口服务,用户可以方便地将其接入到自己的平台中,进…

本地化部署deepseek For_Mac

最近deepseek非常火爆,蒸馏算法的落地,实现了小资源跑大模型,也极大的降低了本地化运行的门槛,为打工人带来了福音;本地化运行可以解决脱网、隐私、审计等重要问题,适合闲暇聊个天、练练英语、完成打工任务 等step1 下载并安装Ollama Ollama是一个开源的 LLM(大型语言模…

数字先锋 | 车企,出海!天翼云AOne擦亮车企“智慧服务”新名片!

近年来,中国汽车市场迎来巨变,消费者的消费习惯不断变迁,价格战愈演愈烈......如何紧跟数字化转型步伐,实现稳健经营,成为车企所面临的时代命题。作为一家科技型制造企业,某车企主营业务涉及汽车及核心三电等产品的研发、制造、销售及服务。公司产品线覆盖新能源汽车和传…

电影《哪吒之魔童闹海》迅雷BT下载[MP4/1.12GB/2.35GB]百度云高清版共享[HD1280p资源已更新]

在那遥远的古代,天地未分,混沌一片,而人间却孕育着无尽的传奇。陈塘关,这个被山海环绕的古城,再一次成为了世人瞩目的焦点。风起云涌间,一个关于哪吒的传奇故事再次拉开序幕,这一次,他不再是那个孤军奋战的孩童,而是携手敖丙,共同面对命运的挑战。电影《哪吒之魔童闹…

帆软单元格换行

在Oracle查询数据时,使用函数WM_CONCAT函数把数据拼成 “A,B,C”格式时,在报表展示中如果在同一个单元格中展示就会显得很拥挤。所以就想通过“,”来实现单元格中换行显示。使用场景 每一行显示一个患者信息,同时该患者的多个诊断、手术等。REPLACE($$$,,,\n)也可参考帆软指…

底层开发必备技能:C#中的位运算

底层开发必备技能:C#中的位运算 在编程的世界里,位运算是程序员掌握底层开发和优化性能的利器。对于那些需要处理二进制数据、优化算法或进行底层操作的开发者来说,理解并熟练使用位运算符是必不可少的技能。本文将详细介绍C#中的位运算符及其应用场景,帮助你更好地理解和运…

关于NVIDIA控制面板无法调节颜色设置

1.排除了显卡驱动过旧的情况具体操作:下载DDU将老版本驱动删除,再从英伟达官网(后缀为.cn)根据自己电脑下载对应型号的驱动,自定义安装——执行清洁安装结果:无效 2.排查系统设置与更新具体操作:用管理员权限打开CMD,依次运行sfc /scannow        DISM /Online…

P1220关路灯双log

加强版。课上讲到的经典例题,以下的时空 \(\mathcal O(n\log^2 V)\) 做法(\(V\) 为路灯位置值域)理论上是人尽皆知的,但是全网搜不到这么搞的题解,估计是这题太久远了。传统区间 DP 无法规避两维状态的问题在于,每次折返/拓展时要用新增时间计算两侧灯消耗的额外能量。考…

Xshell 8 Build 0066绿色特别版发布:功能强大且永久免费使用

软件介绍 Xshell 8 Build 0066 绿色特别版是一款强大且实用的远程连接与管理工具集。Xshell 本身就是备受赞誉的 Linux 远程连接工具,以及强大的 SSH 终端管理器,能帮助用户轻松管理远程服务器。而这个绿色特别版在原版基础上进行了深度优化和处理,由 zdBryan 精心打造。它基…

浏览器事件循环

宏任务浏览器执行的异步代码 eg:JS执行脚本事件、setTimeout/setInterval,ajax请求完成事件、用户交互事件等微任务Js引擎执行的异步代码 eg:Promise对象.then()的回调注意:Promise本身是同步的JS内代码执行流程 执行script脚本事件宏任务里面的同步代码,遇到宏任务/微任务…