14.5 过滤面板 - 尺寸

14.5 过滤面板 - 尺寸

img

实现步骤:


第 1 步:控制器

lib/pages/search/search_filter/controller.dart

1
2
// 尺寸列表
List<KeyValueModel<AttributeModel>> sizes = [];
1
2
// 选中尺寸列表
List<String> sizeKeys = [];
1
2
3
4
5
6
7
8
9
10
11
12
// 读取缓存
void _loadCache() async {
// 尺寸列表
{
String result =
Storage().getString(Constants.storageProductsAttributesSizes);
sizes = jsonDecode(result).map<KeyValueModel<AttributeModel>>((item) {
var arrt = AttributeModel.fromJson(item);
return KeyValueModel(key: "${arrt.name}", value: arrt);
}).toList();
}
}
1
2
3
4
5
@override
void onInit() {
super.onInit();
_loadCache();
}
1
2
3
4
5
// 尺寸选中
void onSizeTap(List<String> keys) {
sizeKeys = keys;
update(["filter_sizes"]);
}

第 2 步:TagsListWidget 组件

lib/common/components/tags_list.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import 'package:flutter/material.dart';

import '../index.dart';

/// 标签列表组件
class TagsListWidget extends StatelessWidget {
// 点击事件
final Function(List<String> keys)? onTap;

// 颜色列表
final List<KeyValueModel<AttributeModel>> itemList;

// 选中的颜色
final List<String> keys;

// 宽
final double? width;

// 高
final double? height;

// 文字颜色
final Color? textColor;

// 文字选中颜色
final Color? textSelectedColor;

// 文字尺寸
final double? textSize;

// 文字 weight
final FontWeight? textWeight;

// 背景颜色
final Color? bgColor;

// 选中背景颜色
final Color? bgSelectedColor;

// 圆角
final double? borderRadius;

// 元素间距
final double? spacing;

// 行间距
final double? runSpacing;

// 是否圆形
final bool? isCircular;

// 尺寸
final double? size;

// 构造
TagsListWidget({
Key? key,
this.onTap,
required this.itemList,
required this.keys,
Color? bgColor,
Color? bgSelectedColor,
Color? textColor,
Color? textSelectedColor,
this.spacing,
this.runSpacing,
this.width = 50,
this.height = 30,
this.borderRadius = 3,
this.textSize,
this.textWeight,
this.isCircular = false,
this.size,
}) : bgColor = bgColor ?? AppColors.surfaceVariant,
bgSelectedColor = bgSelectedColor ?? AppColors.primary,
textColor = textColor ?? AppColors.secondary,
textSelectedColor = textSelectedColor ?? AppColors.onPrimary,
super(key: key);

@override
Widget build(BuildContext context) {
return <Widget>[
for (var item in itemList)
SizedBox(
width: size ?? width,
height: size ?? height,
child: TextWidget.body2(
item.value.name ?? "",
color:
keys.hasValue(item.key) == true ? textSelectedColor : textColor,
textAlign: TextAlign.center,
weight: textWeight ?? FontWeight.bold,
size: textSize,
)
.center()
// 装饰器
.decorated(
// 背景
color:
keys.hasValue(item.key) == true ? bgSelectedColor : bgColor,
// 圆角
borderRadius: BorderRadius.circular(
isCircular == true ? size ?? 24 : borderRadius ?? 3),
)
// 点击
.onTap(() {
if (keys.hasValue(item.key)) {
keys.remove(item.key);
} else {
keys.add(item.key);
}
onTap?.call(keys);
}),
)
].toWrap(
spacing: spacing ?? AppSpace.listItem,
runSpacing: runSpacing ?? AppSpace.listRow,
);
}
}

第 3 步:FilterView 视图

lib/pages/search/search_filter/widgets/filter_view.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 尺寸选择
Widget _buildSizes() {
return GetBuilder<SearchFilterController>(
id: "filter_sizes",
builder: (_) {
return TagsListWidget(
onTap: controller.onSizeTap,
itemList: controller.sizes,
keys: controller.sizeKeys,
bgSelectedColor: AppColors.highlight,
textSelectedColor: AppColors.onPrimary,
isCircular: true,
size: 24,
textSize: 9,
textWeight: FontWeight.w400,
).paddingBottom(AppSpace.listRow * 2);
},
);
}

这里的id: "filter_sizes", 指定后配合 update(["filter_sizes"]); 就可以区域刷新了。

1
2
3
4
5
6
7
8
9
Widget _buildView() {
return <Widget>[
...

// 尺寸
_buildTitle(LocaleKeys.searchFilterSize.tr),
_buildSizes(),

...

提交代码到 git