11.2 右侧商品内容列表编写

11.2 右侧商品内容列表编写

效果

img

实现步骤:


第 1 步:控制器

lib/pages/goods/category/controller.dart

1
2
3
4
5
6
7
8
9
10
// 刷新控制器
final RefreshController refreshController = RefreshController(
initialRefresh: true, // 一开始就自动下拉刷新
);
// 列表
List<ProductModel> items = [];
// 页码
int _page = 1;
// 页尺寸
final int _limit = 20;
1
2
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
// 拉取数据
// isRefresh 是否是刷新
Future<bool> _loadSearch(bool isRefresh) async {
// 拉取数据
var result = await ProductApi.products(ProductsReq(
// 刷新, 重置页数1
page: isRefresh ? 1 : _page,
// 每页条数
prePage: _limit,
// 分类id
category: categoryId.toString(),
));

// 下拉刷新
if (isRefresh) {
_page = 1; // 重置页数1
items.clear(); // 清空数据
}

// 有数据
if (result.isNotEmpty) {
// 页数+1
_page++;

// 添加数据
items.addAll(result);
}

// 是否空
return result.isEmpty;
}

1
2
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"]);
}
1
2
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"]);
}
1
2
3
4
5
6
@override
void onClose() {
super.onClose();
// 刷新控制器释放
refreshController.dispose();
}
1
2
3
4
5
6
// 分类点击事件
void onCategoryTap(int id) async {
categoryId = id;
refreshController.requestRefresh();
update(["left_nav"]);
}

第 2 步:视图

lib/pages/goods/category/view.dart

1
2
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
33
34
35
36
37
38
39
40
/// 右侧商品列表
Widget _buildProductList() {
return GetBuilder<CategoryController>(
id: "product_list",
builder: (controller) {
return SmartRefresher(
controller: controller.refreshController, // 刷新控制器
enablePullUp: true, // 启用上拉加载
onRefresh: controller.onRefresh, // 下拉刷新回调
onLoading: controller.onLoading, // 上拉加载回调
footer: const SmartRefresherFooterWidget(), // 底部加载更多
child: controller.items.isEmpty
?
// 占位图
const PlaceholdWidget()
:
// 商品列表
GridView.builder(
itemCount: controller.items.length, // 数据长度
itemBuilder: (context, index) {
var product = controller.items[index]; // 商品项数据
// 商品项组件
return ProductItemWidget(
product, // 商品
imgHeight: 117.w, // 图片高度
);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 每行2个
mainAxisSpacing: AppSpace.listRow, // 主轴间距
crossAxisSpacing: AppSpace.listItem, // 交叉轴间距
childAspectRatio: 0.8, // 宽高比
),
),
)
// padding 水平间距
.paddingHorizontal(AppSpace.listView);
},
);
}
1
2
3
4
5
6
7
8
9
// 主视图
Widget _buildView() {
return <Widget>[
// 左侧导航
_buildLeftNav(),
// 右侧商品列表
_buildProductList().expanded(),
].toRow();
}

注意需要用 expanded() 撑开右侧内容区

提交代码到 git