10.2 商品列表编写
效果
这个页面适合大家来练手,先不看文档,自己尝试了写下。
 
实现步骤:
第 1 步:i18n
lib/common/i18n/locale_keys.dart
| 12
 3
 
 | static const gFlashSellTitle = "goods_flash_sell_title";
 static const gNewsTitle = "goods_news_title";
 
 | 
lib/common/i18n/locales/locale_en.dart
| 12
 3
 
 | LocaleKeys.gFlashSellTitle: 'Flash Sell',
 LocaleKeys.gNewsTitle: 'New Product',
 
 | 
lib/common/i18n/locales/locale_zh.dart
| 12
 3
 
 | LocaleKeys.gFlashSellTitle: '热卖商品列表',
 LocaleKeys.gNewsTitle: '新商品列表',
 
 | 
第 2 步:首页路由传值
首页控制器发起路由请求
lib/pages/goods/home/controller.dart
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | void onAllTap(bool featured) {
 Get.toNamed(
 RouteNames.goodsProductList,
 arguments: {
 "featured": featured,
 },
 );
 }
 
 | 
注意参数形式 arguments
列表页接收
lib/pages/goods/product_list/controller.dart
| 12
 
 | final bool featured = Get.arguments['featured'] ?? false;
 
 | 
第 3 步:控制器
lib/pages/goods/product_list/controller.dart
| 12
 
 | final bool featured = Get.arguments['featured'] ?? false;
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | final RefreshController refreshController = RefreshController(
 initialRefresh: true,
 );
 
 
 List<ProductModel> items = [];
 
 
 int _page = 1;
 
 
 final int _limit = 20;
 
 | 
如果页面中就一个数据集合推荐用 items 名字,这样方便你代码复用
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | 
 Future<bool> _loadSearch(bool isRefresh) async {
 
 var result = await ProductApi.products(ProductsReq(
 
 page: isRefresh ? 1 : _page,
 
 prePage: _limit,
 ));
 
 
 if (isRefresh) {
 _page = 1;
 items.clear();
 }
 
 
 if (result.isNotEmpty) {
 
 _page++;
 
 
 items.addAll(result);
 
 items.addAll(result);
 items.addAll(result);
 }
 
 
 return result.isEmpty;
 }
 
 | 
// 测试需要多加些数据
items.addAll(result);
items.addAll(result);
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | void onLoading() async {
 if (items.isNotEmpty) {
 try {
 
 var isEmpty = await _loadSearch(false);
 
 if (isEmpty) {
 
 refreshController.loadNoData();
 } else {
 
 refreshController.loadComplete();
 }
 } catch (e) {
 
 refreshController.loadFailed();
 }
 } else {
 
 refreshController.loadNoData();
 }
 update(["product_list"]);
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | void onRefresh() async {
 try {
 await _loadSearch(true);
 refreshController.refreshCompleted();
 } catch (error) {
 
 refreshController.refreshFailed();
 }
 update(["product_list"]);
 }
 
 | 
| 12
 3
 4
 5
 6
 
 | @overridevoid onClose() {
 super.onClose();
 
 refreshController.dispose();
 }
 
 | 
第 4 步:视图
lib/pages/goods/product_list/view.dart
使用 GridView 创建多列滚动组件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | Widget _buildView() {
 return GridView.builder(
 itemCount: controller.items.length,
 itemBuilder: (context, index) {
 var product = controller.items[index];
 return ProductItemWidget(
 product,
 imgHeight: 117.w,
 );
 },
 gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 crossAxisCount: 3,
 mainAxisSpacing: AppSpace.listRow,
 crossAxisSpacing: AppSpace.listItem,
 childAspectRatio: 0.7,
 ),
 );
 }
 
 | 
build 函数
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | @overrideWidget build(BuildContext context) {
 return GetBuilder<ProductListController>(
 init: ProductListController(),
 id: "product_list",
 builder: (_) {
 return Scaffold(
 appBar: mainAppBarWidget(
 titleString: controller.featured == true
 ? LocaleKeys.gFlashSellTitle.tr
 : LocaleKeys.gNewsTitle.tr,
 ),
 body: SmartRefresher(
 controller: controller.refreshController,
 enablePullUp: true,
 onRefresh: controller.onRefresh,
 onLoading: controller.onLoading,
 footer: const SmartRefresherFooterWidget(),
 child: _buildView(),
 ).paddingHorizontal(AppSpace.page),
 );
 },
 );
 }
 
 | 
提交代码到 git