自研flutter3.27+dart3.6+getx實戰抖音短視頻+聊天+直播電商帶貨app商城應用。
flutter_dymall一款基於最新版Flutter3.27+Dart3.x+Getx+mediaKit原創實戰研發抖音app帶貨商城項目。集成了直播+短視頻+聊天三大功能模塊。實現了類似抖音app首頁全屏沉浸式聯動左右滑動頁面模塊、上下滑動短視頻效果。

最新版uniapp+vue3+uv-ui跨三端短視頻+直播+聊天【H5+小程序+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項目已經更新到我的原創作品集,有需要的可以去看看。
flutter3.27仿抖音app商城短視頻+直播+聊天電商
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}); @override Widget 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: () { // 自定義打開右側drawer scaffoldKey.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}); @override State<KeepAliveWrapper> createState() => _KeepAliveWrapperState(); } class _KeepAliveWrapperState extends State<KeepAliveWrapper> with AutomaticKeepAliveClientMixin { @override Widget build(BuildContext context) { super.build(context); return widget.child; } @override bool 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商城的一些知識分享,整個項目涉及到的知識點還是非常多的,限於篇幅就暫時分享到這裏,希望以上分享對大家有些許幫助~
flutter3-deepseek流式AI模板|Flutter3.27+Dio+DeepSeeek聊天ai助手
Uniapp-DeepSeek跨三端AI助手|uniapp+vue3+deepseek-v3流式ai聊天模板
vue3-webseek網頁版AI問答|Vite6+DeepSeek+Arco流式ai聊天打字效果
附上幾個最新跨平台實戰項目案例。
Flutter3-MacOS桌面OS系統|flutter3.32+window_manager客户端OS模板
最新研發flutter3.27+bitsdojo_window+getx客户端仿微信聊天Exe應用
最新版Flutter3.32+Dart3.8跨平台仿微信app聊天界面|朋友圈
最新版uni-app+vue3+uv-ui跨三端仿微信app聊天應用【h5+小程序+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聊天程序
flutter3-winchat桌面端聊天實例|Flutter3+Dart3+Getx仿微信Exe程序
Electron32-ViteOS桌面版os系統|vue3+electron+arco客户端OS管理模板
