16.3 国家选择器

16.3 国家选择器

img

实现步骤:


第 1 步:数据模型

不要把这种基础数据放在安装包中,动态拉取即可

apifox 中查看接口

img

数据结构

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
[
{
"code": "AF",
"name": "非洲",
"countries": [
{
"code": "AO",
"name": "Angolan kwanza",
"currency_code": "AOA",
"currency_pos": "right_space",
"decimal_sep": ",",
"dimension_unit": "cm",
"num_decimals": 2,
"thousand_sep": " ",
"weight_unit": "kg",
"states": [
{
"code": "BGO",
"name": "本戈"
},
{
"code": "BLU",
"name": "本格拉"
},
{
"code": "BIE",
"name": "比耶"
},
{
"code": "CAB",
"name": "卡宾达"
},
{
"code": "CNN",
"name": "库内内"
},
{
"code": "HUA",
"name": "万博"
},
{
"code": "HUI",
"name": "威拉"
},
{
"code": "CCU",
"name": "宽多-库邦戈"
},
{
"code": "CNO",
"name": "北宽扎"
},
{
"code": "CUS",
"name": "南宽扎"
},
{
"code": "LUA",
"name": "罗安达"
},
{
"code": "LNO",
"name": "北隆达"
},
{
"code": "LSU",
"name": "南隆达"
},
{
"code": "MAL",
"name": "马兰热"
},
{
"code": "MOX",
"name": "莫希科"
},
{
"code": "NAM",
"name": "纳米贝"
},
{
"code": "UIG",
"name": "威热"
},
{
"code": "ZAI",
"name": "扎伊尔"
}
]
}
]
}
]
]

一次性的把大陆、国家、洲省 数据都拉取下来

创建模型

lib/common/models/woo/continents_model

img

修正

lib/common/models/woo/continents_model/state.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class State {
String? code;
String? name;

State({
this.code,
this.name,
});

factory State.fromJson(Map<String, dynamic> json) => State(
code: "${json['code']}",
name: "${json['name']}",
);

Map<String, dynamic> toJson() => {
'code': code,
'name': name,
};
}

导包

lib/common/models/index.dart

1
2
export './woo/continents_model/continents_model.dart';
export './woo/continents_model/country.dart';

第 2 步:请求 api

lib/common/api/user.dart

1
2
3
4
5
6
7
8
9
10
11
12
/// 大陆国家洲省列表
static Future<List<ContinentsModel>> continents() async {
var res = await WPHttpService.to.get(
'/users/continents',
);

List<ContinentsModel> continents = [];
for (var item in res.data) {
continents.add(ContinentsModel.fromJson(item));
}
return continents;
}

第 3 步:控制器

lib/pages/my/my_address/controller.dart

1
2
3
4
// 大陆国家洲省
List<ContinentsModel> continents = [];
// 大陆国家数据
List<Map<KeyValueModel, List<KeyValueModel>>> countriesList = [];
1
2
// 国家选择
List<int> countrySels = [];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 拉取大陆国家洲省数据
Future<void> _fetchContinents() async {
continents = await UserApi.continents();
countriesList = List.generate(continents.length, (index) {
var entity = continents[index];
List<KeyValueModel> countryList = [];
for (Country country in entity.countries ?? []) {
countryList.add(KeyValueModel<String>(
key: country.code ?? "-",
value: country.name ?? "-",
));
}
return {
KeyValueModel<String>(
key: entity.code ?? "-",
value: entity.name ?? "-",
): countryList,
};
});
}
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
// 初始化
Future<void> _initData() async {
// 拉取 大陆国家数据
await _fetchContinents();

// 国家代码
String countryCode = countryController.text;

// 国家选着器 - 选中 index
for (var i = 0; i < continents.length; i++) {
// 大陆
var continent = continents[i];
// 检查是否有选中的国家
int iCountryIndex =
continent.countries?.indexWhere((el) => el.code == countryCode) ?? 0;
if (iCountryIndex > 0) {
countrySels = [
i,
iCountryIndex,
];
break;
}
}

update(["my_address"]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 国家选择
void onCountryPicker() async {
ActionBottomSheet.data(
title: 'Country',
context: Get.context!,
// 数据
adapter: PickerDataAdapter<KeyValueModel<String>>(
pickerdata: countriesList,
),
// 默认选中 [index, index]
selecteds: countrySels,
// 确认回调
onConfirm: (value) {
if (value.isEmpty) return;
if (value.length == 2) {
countryController.text = '${value[1].key}';
}
},
);
}

第 4 步:视图

lib/pages/my/my_address/view.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 表单
Widget _buildForm() {
return Form(
key: controller.formKey, //设置globalKey,用于后面获取FormState
autovalidateMode: AutovalidateMode.onUserInteraction,
child: <Widget>[

// Country
TextFormWidget(
onTap: controller.onCountryPicker,
readOnly: true,
isMustBeEnter: true,
controller: controller.countryController,
labelText: LocaleKeys.addressCountry.tr,
validator: Validatorless.multiple([
Validatorless.required("The field is obligatory"),
]),
),

...

提交代码到 git