Flutter 鸿蒙开发:基于组件化拆分,快速实现电商首页布局
本文参考Flutter鸿蒙开发指南(五):实现首页基础布局-CSDN博客
本文记录操作过程以及遇到的问题
在上一节中,我们已完成电商App底部Tab栏的实现,成功搭建了App的基础框架。这一节,我们将聚焦首页开发,逐步实现轮播图、分类、推荐、爆款、商品列表等核心模块,完成首页基础布局的搭建,让App首页具备完整的可视化效果。
一、项目结构搭建
首页布局由多个独立子组件组成,为了保证项目结构清晰、便于后续维护和扩展,我们先在指定目录下新建所需组件文件。
1.1 新建项目组件
在lib/components下新建Home文件夹,再分别新建以下文件:
- HmSlider.dart文件,用于实现首页顶部轮播图组件
- HmCategory.dart文件,用于实现首页横向滚动分类组件
- HmSuggestion.dart文件,用于实现首页推荐区域组件
- HmHot.dart文件,用于实现首页爆款推荐组件
- HmMoreList.dart文件,用于实现首页商品无限滚动列表组件

【新手提示】:在Android Studio或VS Code中,新建Dart文件后,输入快捷指令stful,即可一键生成StatefulWidget组件的模板代码(包含组件类和对应的状态类),无需手动编写基础结构,提升开发效率。
1.2 初始化组件代码
HmCatrgory.dart 初始化代码
import 'package:flutter/material.dart';
class HmCategory extends StatefulWidget {
const HmCategory({super.key});
@override
State<HmCategory> createState() => _HmCategoryState();
}
class _HmCategoryState extends State<HmCategory> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
HmHot.dart 初始化代码
import 'package:flutter/material.dart';
class HmHot extends StatefulWidget {
const HmHot({super.key});
@override
State<HmHot> createState() => _HmHotState();
}
class _HmHotState extends State<HmHot> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
HmMoreList.dart 初始化代码
import 'package:flutter/material.dart';
class HmMorelist extends StatefulWidget {
const HmMorelist({super.key});
@override
State<HmMorelist> createState() => _HmMorelistState();
}
class _HmMorelistState extends State<HmMorelist> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
HmSlider.dart 初始化代码
import 'package:flutter/material.dart';
class HmSlider extends StatefulWidget {
const HmSlider({super.key});
@override
State<HmSlider> createState() => _HmSliderState();
}
class _HmSliderState extends State<HmSlider> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
HmSuggestion.dart 代码
import 'package:flutter/material.dart';
class HmSuggestion extends StatefulWidget {
const HmSuggestion({super.key});
@override
State<HmSuggestion> createState() => _HmSuggestionState();
}
class _HmSuggestionState extends State<HmSuggestion> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
二、编写组件对应代码
2.1 轮播图组件代码
HmSlider.dart代码
轮播图是电商App首页的核心模块之一,此处我们先实现基础的轮播图容器(蓝色背景+文字提示),后续可扩展为真实的图片轮播效果,代码如下:
import 'package:flutter/material.dart';
class HmSlider extends StatefulWidget {
const HmSlider({super.key});
@override
State<HmSlider> createState() => _HmSliderState();
}
class _HmSliderState extends State<HmSlider> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
height: 300,
alignment: Alignment.center,
child:
Text('轮播图', style: TextStyle(color: Colors.white, fontSize: 20)));
}
}
整合到首页
修改Home/index.dart代码
轮播图组件编写完成后,需要将其导入到首页核心文件中,使用CustomScrollView实现滚动布局(适配后续更多组件的滚动需求),代码如下:
import 'package:flutter/cupertino.dart';
import 'package:xiuhu_mall/components/Home/HmSlider.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
//获取滚动容器的内容
List<Widget> _getScrollChildren() {
return [
//包裹普通widget的sliver家族的组件内容
SliverToBoxAdapter(child: HmSlider()),//轮播图组件
];
}
@override
Widget build(BuildContext context) {
//CustomScrollview要求:必须是sliver家族的内容
return CustomScrollView(slivers: _getScrollChildren());
}
}
效果展示

2.2 分类组件代码
HmCategory.dart代码
分类组件用于展示商品分类(如服饰、家电、美食等),此处实现横向可滚动的分类列表,支持点击选中效果。
import 'package:flutter/material.dart';
class HmCategory extends StatefulWidget {
const HmCategory({super.key});
@override
State<HmCategory> createState() => _HmCategoryState();
}
class _HmCategoryState extends State<HmCategory> {
@override
Widget build(BuildContext context) {
//返回一个横向滚动的组件,但是得设置高度。但是ListView自身不能设置高度.能设置高度的只有Container和SizeBox
return SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return Container(
alignment: Alignment.center,
width: 80,
height: 100,
color: Colors.blue,
child: Text("分类$index", style: TextStyle(color: Colors.white)),
margin: EdgeInsets.symmetric(horizontal: 10),
);
}),
);
}
}
报错以及解决方案

【报错内容】:Container同时设置了color和decoration导致的冲突。
【报错原因】:Flutter中,Container的color属性是decoration(装饰)的简写形式,两者不能同时设置,否则会出现语法冲突,编译器无法识别优先级。
【解决方案】:将color属性移到decoration的BoxDecoration中,同时我们优化代码,添加点击选中效果(选中时改变背景色和文字样式),修改后的完整HmCategory.dart代码如下:
import 'package:flutter/material.dart';
class HmCategory extends StatefulWidget {
const HmCategory({super.key});
@override
State<HmCategory> createState() => _HmCategoryState();
}
class _HmCategoryState extends State<HmCategory> {
int _selectedIndex = -1;
@override
Widget build(BuildContext context) {
return SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
padding: const EdgeInsets.symmetric(horizontal: 16),
itemBuilder: (BuildContext context, int index) {
bool isSelected = _selectedIndex == index;
return GestureDetector(
onTap: () {
setState(() => _selectedIndex = index);
print("点击了分类$index");
},
child: Container(
alignment: Alignment.center,
width: 80,
height: 80,
// 把color移到decoration里,解决冲突
decoration: BoxDecoration(
color: isSelected ? Theme.of(context).primaryColor : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 3,
offset: const Offset(0, 2),
)
],
),
margin: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
"分类$index",
style: TextStyle(
color: isSelected ? Colors.white : Colors.black87,
fontSize: 16,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
),
);
},
),
);
}
}
更新首页代码
修改Home/index.dart代码
import 'package:flutter/material.dart';
import 'package:xiuhu_mall/components/Home/HmSlider.dart';
import 'package:xiuhu_mall/components/Home/HmCategory.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
// 用SingleChildScrollView实现页面滚动,包裹Column放轮播图+分类
return SingleChildScrollView(
child: Column(
children: [
// 1. 轮播图组件
HmSlider(),
// 2. 分类组件(加个上下间距更美观)
const SizedBox(height: 10),
HmCategory(),
// 可继续添加其他组件
],
),
);
}
}
效果

2.3 推荐组件代码
HmSuggestion.dart代码
推荐组件用于展示推荐商品或活动,此处实现基础的推荐容器,添加左右内边距,避免贴边,代码如下:
import 'package:flutter/material.dart';
class HmSuggestion extends StatefulWidget {
const HmSuggestion({super.key});
@override
State<HmSuggestion> createState() => _HmSuggestionState();
}
class _HmSuggestionState extends State<HmSuggestion> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
alignment: Alignment.center,
height: 300,
child: Text(
"推荐",
style: TextStyle(color: Colors.white),
));
}
}
更新首页代码
修改Home/index.dart代码:
导入推荐组件,优化首页布局,添加全局左右内边距,调整组件间距
import 'package:flutter/material.dart';
import 'package:xiuhu_mall/components/Home/HmSlider.dart';
import 'package:xiuhu_mall/components/Home/HmCategory.dart';
import 'package:xiuhu_mall/components/Home/HmSuggestion.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
// 用SingleChildScrollView实现页面滚动,包裹Column放轮播图+分类+推荐
return SingleChildScrollView(
// 2. 给整个滚动区域加左右内边距,避免组件贴边
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
// 1. 轮播图组件
HmSlider(),
// 2. 分类组件
const SizedBox(height: 16),
HmCategory(),
// 3. 补全推荐组件(加上间距,和分类组件呼应)
const SizedBox(height: 16),
HmSuggestion(),
// 4. 底部加间距,避免推荐组件贴底(和底部Tab栏留出空隙)
const SizedBox(height: 20),
],
),
);
}
}
效果

2.4 爆款推荐组件代码
HmHot.dart代码
爆款推荐组件用于展示热门商品,实现两个横向均分的爆款容器,代码如下:
import 'package:flutter/material.dart';
class HmHot extends StatefulWidget {
const HmHot({super.key});
@override
State<HmHot> createState() => _HmHotState();
}
class _HmHotState extends State<HmHot> {
@override
Widget build(BuildContext context) {
return Container(
height: 200,
color: Colors.blue,
alignment: Alignment.center,
child: Text('爆款推荐', style: TextStyle(color: Colors.white)),
);
}
}
优化推荐组件
为了让推荐组件和爆款组件风格统一,给推荐组件添加左右内边距,修改后的HmSuggestion.dart代码如下:
import 'package:flutter/material.dart';
class HmSuggestion extends StatefulWidget {
const HmSuggestion({super.key});
@override
State<HmSuggestion> createState() => _HmSuggestionState();
}
class _HmSuggestionState extends State<HmSuggestion> {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
color: Colors.blue,
alignment: Alignment.center,
height: 300,
child: Text(
"推荐",
style: TextStyle(color: Colors.white),
)));
}
}
更新首页代码
将首页滚动布局改回CustomScrollView(适配后续无限滚动列表),导入爆款组件,用Flex+Expanded实现两个爆款容器横向均分,修改后的Home/index.dart代码如下:
import 'package:flutter/cupertino.dart';
import 'package:xiuhu_mall/components/Home/HmCategory.dart';
import 'package:xiuhu_mall/components/Home/HmHot.dart';
import 'package:xiuhu_mall/components/Home/HmSlider.dart';
import 'package:xiuhu_mall/components/Home/HmSuggestion.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
//获取滚动容器的内容
List<Widget> _getScrollChildren() {
return [
//包裹普通widget的sliver家族的组件内容
SliverToBoxAdapter(child: HmSlider()), //轮播图组件
//放置分类组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
//SliverGrid SliverList指南纵向排列
SliverToBoxAdapter(child: HmCategory()), //分类组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
SliverToBoxAdapter(child: HmSuggestion()), //推荐组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
//Flex和Expanded配合起来可以均分比例
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Flex(
direction: Axis.horizontal,
children: [
Expanded(child: HmHot()),
SizedBox(
width: 10,
),
Expanded(child: HmHot()),
],
)),
),
];
}
@override
Widget build(BuildContext context) {
//CustomScrollview要求:必须是sliver家族的内容
return CustomScrollView(slivers: _getScrollChildren());
}
}
效果

2.5 商品无限滚动列表组件
HmMoreList.dart代码
商品列表组件用于展示大量商品,实现无限滚动效果(此处用SliverGrid实现两列网格布局,模拟商品列表),代码如下:
import 'package:flutter/material.dart';
class HmMorelist extends StatefulWidget {
const HmMorelist({super.key});
@override
State<HmMorelist> createState() => _HmMorelistState();
}
class _HmMorelistState extends State<HmMorelist> {
@override
Widget build(BuildContext context) {
//必须是Sliver家族的组件
return SliverGrid.builder(gridDelegate:
//网格是两列
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
itemBuilder: (BuildContext context, int index) {
return Container(
child: Text("商品", style: TextStyle(color: Colors.white),),
color: Colors.blue,
alignment: Alignment.center,
);
});
}
}
更新首页代码
导入商品列表组件,添加间距,将其整合到首页底部,修改后的Home/index.dart代码如下:
import 'package:flutter/cupertino.dart';
import 'package:xiuhu_mall/components/Home/HmCategory.dart';
import 'package:xiuhu_mall/components/Home/HmHot.dart';
import 'package:xiuhu_mall/components/Home/HmMoreList.dart';
import 'package:xiuhu_mall/components/Home/HmSlider.dart';
import 'package:xiuhu_mall/components/Home/HmSuggestion.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
//获取滚动容器的内容
List<Widget> _getScrollChildren() {
return [
//包裹普通widget的sliver家族的组件内容
SliverToBoxAdapter(child: HmSlider()), //轮播图组件
//放置分类组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
//SliverGrid SliverList指南纵向排列
SliverToBoxAdapter(child: HmCategory()), //分类组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
SliverToBoxAdapter(child: HmSuggestion()), //推荐组件
SliverToBoxAdapter(child: SizedBox(height: 10)),
//Flex和Expanded配合起来可以均分比例
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Flex(
direction: Axis.horizontal,
children: [
Expanded(child: HmHot()),
SizedBox(
width: 10,
),
Expanded(child: HmHot()),
],
)),
),
SliverToBoxAdapter(child: SizedBox(height: 10)),
HmMorelist(),//无限滚动列表
];
}
@override
Widget build(BuildContext context) {
//CustomScrollview要求:必须是sliver家族的内容
return CustomScrollView(slivers: _getScrollChildren());
}
}
效果

三、Git上传代码
完成开发并测试通过后,使用Git提交代码,保存当前开发进度,执行以下命令(依次在控制台输入):
git add .
git commit -m "完成首页基础布局"
git push
【新手提示】:若执行git push时报错,需先关联远程仓库(执行git remote add origin 远程仓库地址),再执行推送命令;若忘记远程仓库地址,可在GitHub、Gitee等平台查看对应仓库的地址。
四、总结
本次开发我们基于上一节实现的底部Tab栏,完成了电商App首页基础布局的搭建,核心收获如下:
- 组件化拆分:将首页拆分为轮播图、分类、推荐、爆款、商品列表5个独立子组件,让项目结构更清晰,便于后续维护和功能扩展。
- 布局技能提升:熟练使用CustomScrollView、SingleChildScrollView实现页面滚动,掌握SliverToBoxAdapter、SliverGrid的使用方法,学会用Flex+Expanded实现组件横向均分。
- 报错解决能力:遇到Container的color和decoration冲突问题,通过将color整合到decoration中成功解决,积累了基础的Flutter语法报错解决经验。
- 细节优化技巧:通过添加内边距、间距、圆角、阴影,提升页面美观度;通过点击事件实现分类选中效果,增强页面交互性。
本次实现的首页布局为基础版本,后续可进行进一步优化:将占位的蓝色容器替换为真实的图片、完善商品列表的数据渲染、实现轮播图的自动切换和点击跳转、优化组件的响应式布局(适配不同屏幕尺寸)等。
最后
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)