Flutter 鸿蒙开发:电商 App 底部 Tab 栏实现
本文介绍了Flutter实现电商App底部Tab栏的基础开发流程。
·
本文参考Flutter鸿蒙开发指南(四):主页Tab栏实现-CSDN博客
在上一节中,我们完成了Dio 库实现简单的网络请求。这一节,我们来研究电商 App 底部 Tab 栏的实现。
一、环境准备:Git回退代码(可选)
若上一节开发后有多余代码干扰,可将工作目录和暂存区完全恢复到上一次提交的干净状态,执行以下Git命令即可:
git reset --hard HEAD
提示:若无需回退,可直接跳过本步骤,确保项目无报错即可进入下一步开发。
二、资源准备:导入Tab栏图标资源
Tab栏需要用到“选中/未选中”两种状态的图标,共5个(含备用图标),获取及导入步骤如下:
- https://atomgit.com/Deng666/shangcheng访问仓库地址:https://atomgit.com/Deng666/shangcheng
- 在仓库中找到「assets」文件夹,下载其中的图标图片
- 在自己的Flutter项目中,新建路径「lib/assets/」,将下载的图片复制粘贴到该文件夹下
- 配置资源路径:打开项目根目录的「pubspec.yaml」文件,解开「assets」相关注释,并修改为以下配置(确保资源能被Flutter识别):
用到的图标图片:

解开这里注释

然后把代码更改成图中样式

代码如下:
flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- lib/assets/
三、核心开发:编写Tab栏及页面代码
3.1 第一步:配置入口,指定Tab栏为主页
在lib/pages/Main/index.dart路径下,编写代码如下:
import 'package:flutter/material.dart';
/*
* @author:Lionel689
* @date:2025-1-25
*[Tabs:首页]
*/
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
//定义数据 根据数据进行渲染4个导航 List<Map>:key value <String,String>是泛型
//一般应用程序的导航是固定的
final List<Map<String, String>> _tabList = [
{
"icon": "lib/assets/ic_public_home_normal.png", //未选中
"active_icon": "lib/assets/ic_public_home_active.png",//选中
"text": "首页",
},
{
"icon": "lib/assets/ic_public_pro_normal.png", //未选中
"active_icon": "lib/assets/ic_public_pro_active.png",//选中
"text": "分类",
},
{
"icon": "lib/assets/ic_public_cart_normal.png", //未选中
"active_icon": "lib/assets/ic_public_cart_active.png",//选中
"text": "购物车",
},
{
"icon": "lib/assets/ic_public_my_normal.png", //未选中
"active_icon": "lib/assets/ic_public_my_active.png",//选中
"text": "我的",
},
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("主页"),
),
);
}
}
修改项目入口文件main代码:
import 'package:flutter/material.dart';
import 'package:xiuhu_mall/pages/Main/index.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'xiuhu商城',
theme: ThemeData(
// 保留主题配置,也可以根据需要修改
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// 将首页从默认的 MyHomePage 改为 MainPage(底部Tab栏页面)
home: const MainPage(),
);
}
}

3.2 第二步:编写Tab栏核心代码

此时还无法点击导航栏。原因是缺少了关键的当前选中索引管理。
3.3 第三步:编写4个Tab对应的子页面
新建以下四个文件夹:Cart文件夹下的index.dart,Category文件夹下的index.dart,Home文件夹下的index.dart,Mine文件夹下的index.dart。
新增代码如下:
修改Tab栏:lib/pages/Main/index.dart代码
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:xiuhu_mall/pages/Cart/index.dart';
import 'package:xiuhu_mall/pages/Category/index.dart';
import 'package:xiuhu_mall/pages/Home/home.dart';
import 'package:xiuhu_mall/pages/Mine/mine.dart';
/*
* @author:Lionel689
* @date:2025-2-1
*[Tabs:首页]
*/
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
//定义数据 根据数据进行渲染4个导航 List<Map>:key value <String,String>是泛型
//一般应用程序的导航是固定的
final List<Map<String, String>> _tabList = [
{
"icon": "lib/assets/ic_public_home_normal.png", //未选中
"active_icon": "lib/assets/ic_public_home_active.png", //选中
"text": "首页",
},
{
"icon": "lib/assets/ic_public_pro_normal.png", //未选中
"active_icon": "lib/assets/ic_public_pro_active.png", //选中
"text": "分类",
},
{
"icon": "lib/assets/ic_public_cart_normal.png", //未选中
"active_icon": "lib/assets/ic_public_cart_active.png", //选中
"text": "购物车",
},
{
"icon": "lib/assets/ic_public_my_normal.png", //未选中
"active_icon": "lib/assets/ic_public_my_active.png", //选中
"text": "我的",
},
];
int _currentIndex = 0;
//返回底部渲染的四个分类
List<BottomNavigationBarItem> _getTabBarWidget() {
return List.generate(_tabList.length, (int index) {
return BottomNavigationBarItem(
icon: Image.asset(
_tabList[index]["icon"]!, //正常显示图标
width: 30,
height: 30,
),
activeIcon: Image.asset(
_tabList[index]["active_icon"]!,
width: 30,
height: 30,
),
label: _tabList[index]["text"],
);
});
}
List<Widget> _getChildren() {
return [HomeView(), CategoryView(), CartView(), MineView()];
}
@override
Widget build(BuildContext context) {
return Scaffold(
//SafeArea会避开安全区组件
body: SafeArea(
child: IndexedStack(
index: _currentIndex,
children: _getChildren(), //放置四个组件
)),
bottomNavigationBar: BottomNavigationBar(
showUnselectedLabels: true,
unselectedItemColor: Colors.black,
selectedItemColor: Colors.black,
onTap: (int index) {
//index就是当前点击的索引
_currentIndex = index;
setState(() {});
},
items: _getTabBarWidget(),
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex, //选中下标
));
}
}
分类页面:lib/pages/Cart/index.dart代码
import 'package:flutter/cupertino.dart';
//View结尾表示不是页面,Page结尾一般才是页面
class CartView extends StatefulWidget {
const CartView({super.key});
@override
State<CartView> createState() => _CartViewState();
}
class _CartViewState extends State<CartView> {
@override
Widget build(BuildContext context) {
return Center(
child: Text("购物车"),
);
}
}
购物车页面:lib/pages/Category/index.dart代码
import 'package:flutter/cupertino.dart';
class CategoryView extends StatefulWidget {
const CategoryView({super.key});
@override
State<CategoryView> createState() => _CategoryViewState();
}
class _CategoryViewState extends State<CategoryView> {
@override
Widget build(BuildContext context) {
return Center(
child: Text("分类"),
);
}
}
首页页面:lib/pages/Home/index.dart代码
import 'package:flutter/cupertino.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _CartViewState();
}
class _CartViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
return Center(
child: Text("首页"),
);
}
}
我的页面:lib/pages/Mine/index.dart代码
import 'package:flutter/cupertino.dart';
class MineView extends StatefulWidget {
const MineView({super.key});
@override
State<MineView> createState() => _MineViewState();
}
class _MineViewState extends State<MineView> {
@override
Widget build(BuildContext context) {
return Center(
child: Text("我的"),
);
}
}
四、运行结果
完成以上代码编写后,运行Flutter项目(双端均可测试,鸿蒙端、Android端效果一致),预期实现以下效果:
- App启动后,默认显示「首页」,底部Tab栏默认选中「首页」图标(高亮显示)。
- 点击底部「首页、分类、购物车、我的」Tab,可快速切换到对应页面,选中的Tab图标和文本会高亮。
- 页面切换时,顶部状态栏、底部Tab栏不遮挡内容(SafeArea生效),页面状态保持稳定(IndexedStack生效)。




五、提交代码
完成Tab栏开发并测试通过后,使用Git提交代码,保存当前开发进度,执行以下命令(依次在控制台输入):
git add .
git commit -m "完成主页tab实现"
git push
最后,欢迎加入开源鸿蒙跨平台社区
https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)