【OpenHarmony】Flutter鸿蒙实战:打造商城分类导航模块
在电商类应用开发中,首页的分类导航是一个核心功能模块。用户通过横向滚动的分类列表快速找到目标商品类型。本文将带领大家从零开始,使用Flutter框架结合AI编程助手,完成一个完整的商城分类导航功能开发。



项目背景
在电商类应用开发中,首页的分类导航是一个核心功能模块。用户通过横向滚动的分类列表快速找到目标商品类型。本文将带领大家从零开始,使用Flutter框架结合AI编程助手,完成一个完整的商城分类导航功能开发。
我们将实现的功能包括:
- 动态加载服务器端分类数据
- 分类图标与文字的展示
- 横向滚动交互效果
- 圆角卡片式UI设计
实现步骤
第一步:配置API基础信息
首先,我们需要在项目中定义API相关常量。创建配置文件可以统一管理接口地址,便于后续维护。
修改文件:lib/constants/config.dart
/// API配置中心
class ApiConfig {
/// 服务器基础地址
static const String baseUrl = "https://meikou-api.itheima.net/";
/// 网络请求超时时长(秒)
static const int timeoutDuration = 10;
/// 业务接口成功状态码
static const String successCode = "1";
}
/// 接口路径定义
class ApiPath {
/// 首页轮播图数据接口
static const String bannerList = "/home/banner";
/// 首页分类列表接口
static const String categoryList = "/home/category/head";
}
第二步:构建数据模型
分类数据采用树形结构,每个分类包含多个子分类。我们需要创建对应的数据模型类,并实现JSON序列化功能。
接口数据结构预览:
创建文件:lib/models/category_model.dart
/// 分类数据模型
class CategoryModel {
/// 分类ID
final String id;
/// 分类名称
final String name;
/// 分类图标URL
final String? iconUrl;
/// 子分类列表
final List<CategoryModel>? subCategories;
CategoryModel({
required this.id,
required this.name,
this.iconUrl,
this.subCategories,
});
/// 从JSON数据创建实例(工厂构造函数)
factory CategoryModel.fromJson(Map<String, dynamic> json) {
return CategoryModel(
id: json["id"]?.toString() ?? "",
name: json["name"]?.toString() ?? "",
iconUrl: json["picture"]?.toString(),
subCategories: json["children"] != null
? (json["children"] as List)
.map((item) => CategoryModel.fromJson(item as Map<String, dynamic>))
.toList()
: null,
);
}
}
第三步:封装网络请求层
为了更好地管理API调用,我们需要创建一个专门的API服务层。
创建文件:lib/services/home_service.dart
import 'package:dio/dio.dart';
import '../constants/config.dart';
import '../models/category_model.dart';
/// 首页数据服务
class HomeService {
static final Dio _dio = Dio(
BaseOptions(
baseUrl: ApiConfig.baseUrl,
connectTimeout: Duration(seconds: ApiConfig.timeoutDuration),
receiveTimeout: Duration(seconds: ApiConfig.timeoutDuration),
),
);
/// 获取分类列表数据
static Future<List<CategoryModel>> fetchCategories() async {
try {
final response = await _dio.get(ApiPath.categoryList);
// 判断业务状态码
if (response.data['code'] == ApiConfig.successCode) {
final List<dynamic> dataList = response.data['result'];
return dataList
.map((item) => CategoryModel.fromJson(item as Map<String, dynamic>))
.toList();
} else {
throw Exception('业务错误: ${response.data['message']}');
}
} catch (e) {
throw Exception('网络请求失败: $e');
}
}
}
第四步:实现分类列表组件
接下来我们创建UI组件,以横向滚动的方式展示分类列表。
创建文件:lib/widgets/category_bar.dart
先创建一个基础版本,验证布局结构:
import 'package:flutter/material.dart';
import '../models/category_model.dart';
/// 首页分类导航栏组件
class CategoryBar extends StatefulWidget {
/// 分类数据列表
final List<CategoryModel> categories;
const CategoryBar({
super.key,
required this.categories,
});
State<CategoryBar> createState() => _CategoryBarState();
}
class _CategoryBarState extends State<CategoryBar> {
Widget build(BuildContext context) {
// 使用SizedBox固定高度,ListView不能直接设置高度
return SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal, // 横向滚动
itemCount: widget.categories.length,
itemBuilder: (context, index) {
final category = widget.categories[index];
return _buildCategoryItem(category);
},
),
);
}
Widget _buildCategoryItem(CategoryModel category) {
return Container(
width: 80,
margin: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.network(
category.iconUrl ?? '',
width: 40,
height: 40,
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.category, size: 40);
},
),
const SizedBox(height: 4),
Text(
category.name,
style: const TextStyle(color: Colors.white),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
}
}
第五步:集成到首页
在首页中调用分类API并展示数据。
修改文件:lib/pages/home_page.dart
import 'package:flutter/material.dart';
import '../services/home_service.dart';
import '../models/category_model.dart';
import '../widgets/category_bar.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
/// 分类数据列表
List<CategoryModel> _categories = [];
/// 加载状态
bool _isLoading = false;
void initState() {
super.initState();
_loadCategoryData();
}
/// 加载分类数据
Future<void> _loadCategoryData() async {
setState(() => _isLoading = true);
try {
final data = await HomeService.fetchCategories();
setState(() {
_categories = data;
_isLoading = false;
});
} catch (e) {
setState(() => _isLoading = false);
// 实际项目中应该用toast提示
debugPrint('加载失败: $e');
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('商城首页')),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: CustomScrollView(
slivers: [
// 分类导航栏
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: CategoryBar(categories: _categories),
),
),
// 其他模块...
],
),
);
}
}
第六步:优化UI设计
现在我们来美化分类卡片,采用浅灰色圆角背景的设计风格。
优化后的 lib/widgets/category_bar.dart:
import 'package:flutter/material.dart';
import '../models/category_model.dart';
/// 首页分类导航栏组件
class CategoryBar extends StatefulWidget {
final List<CategoryModel> categories;
const CategoryBar({
super.key,
required this.categories,
});
State<CategoryBar> createState() => _CategoryBarState();
}
class _CategoryBarState extends State<CategoryBar> {
Widget build(BuildContext context) {
return SizedBox(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 12),
itemCount: widget.categories.length,
itemBuilder: (context, index) {
final category = widget.categories[index];
return _buildCategoryItem(category);
},
),
);
}
Widget _buildCategoryItem(CategoryModel category) {
return Container(
width: 70,
margin: const EdgeInsets.only(right: 12),
decoration: BoxDecoration(
color: const Color(0xFFE7E8EA), // 浅灰色背景
borderRadius: BorderRadius.circular(35), // 圆角效果
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 分类图标
Image.network(
category.iconUrl ?? '',
width: 40,
height: 40,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return const Icon(
Icons.image_outlined,
size: 40,
color: Colors.grey,
);
},
),
const SizedBox(height: 6),
// 分类名称
Text(
category.name,
style: const TextStyle(
fontSize: 12,
color: Colors.black87,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
],
),
);
}
}

核心要点总结
1. 数据模型设计
- 使用
factory构造函数实现JSON解析 - 处理可空字段和嵌套数组
- 使用
??操作符提供默认值
2. 网络请求封装
- 统一管理baseUrl和超时配置
- 业务状态码与HTTP状态码分离处理
- 使用try-catch捕获异常
3. UI组件技巧
ListView横向滚动需配合SizedBox设置高度Decoration实现圆角和背景色Image.network配合errorBuilder处理加载失败
代码提交
完成开发后,建议使用Git进行版本管理:
git add .
git commit -m "feat: 实现首页分类导航功能"
相关推荐阅读:
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)