Cascader 级联选择器API
参考官方示例代码
在自己的模板中使用:view
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'index.dart';
class HomePage extends GetView<HomeController> {
const HomePage({super.key});
// 主视图
Widget _buildView(BuildContext context) {
return <Widget>[
_buildHorizontalCascader(context),
].toColumn();
}
Widget _buildHorizontalCascader(BuildContext context) {
return GestureDetector(
onTap: () {
TDCascader.showMultiCascader(
context,
title: '选择地址',
subTitles: ['请选择省份', '请选择城市', '请选择区/县'],
data: controller.cityListData.map((item) => item.toJson()).toList(),
initialData: controller.initData,
theme: 'tab',
onChange: (selectData) {
controller.onTapAddress(selectData);
},
onClose: () {
Navigator.of(context).pop();
},
);
},
child: _buildSelectRow(context, controller.selected_1 ?? '', '选择地区'),
);
}
Widget _buildSelectRow(BuildContext context, String output, String title) {
return Container(
color: TDTheme.of(context).whiteColor1,
height: 56,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16),
child: TDText(
title,
font: TDTheme.of(context).fontBodyLarge,
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 16, left: 16),
child: Row(
children: [
Expanded(
child: TDText(
output,
font: TDTheme.of(context).fontBodyLarge,
textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Padding(
padding: const EdgeInsets.only(left: 2),
child: Icon(
TDIcons.chevron_right,
color: TDTheme.of(context).fontGyColor3.withOpacity(0.4),
),
),
],
),
),
),
],
),
const TDDivider(
margin: EdgeInsets.only(
left: 16,
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return GetBuilder<HomeController>(
init: HomeController(),
id: "home",
builder: (_) {
return Scaffold(
appBar: AppBar(title: const Text("home")),
body: SafeArea(
child: _buildView(context),
),
);
},
);
}
}
controller
import 'dart:convert';
import 'package:demo/common/index.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
class HomeController extends GetxController {
HomeController();
String? initData;
String? selected_1;
List<CityListModel> cityListData = [];
@override
void onReady() {
super.onReady();
_loadCityData();
}
void _loadCityData() async {
try {
// 读取本地 JSON 文件
var data = await rootBundle.loadString('assets/img/city.json');
// 解析 JSON 数据
List<dynamic> jsonData = json.decode(data);
// 将 JSON 数据转换为 List<Map<String, dynamic>>
cityListData = jsonData.map((item) => CityListModel.fromJson(item as Map<String, dynamic>)).toList();
print('cityListData: $cityListData');
update(["home"]);
} catch (e) {
print('Error loading city data: $e');
}
}
void onTapAddress(List<MultiCascaderListModel> selectData) {
List result = [];
int len = selectData.length;
initData = selectData[len - 1].value!;
selectData.forEach((element) {
result.add(element.label);
});
selected_1 = result.join('/');
update(["home"]);
}
}
根据官方示例制作
CityListModel模型
import 'child.dart';
class CityListModel {
String? label;
String? value;
List<Child>? children;
CityListModel({this.label, this.value, this.children});
factory CityListModel.fromJson(Map<String, dynamic> json) => CityListModel(
label: json['label'] as String?,
value: json['value'] as String?,
children: (json['children'] as List<dynamic>?)
?.map((e) => Child.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> toJson() => {
'label': label,
'value': value,
'children': children?.map((e) => e.toJson()).toList(),
};
}
class Child {
String? label;
String? value;
List<Child>? children;
Child({this.label, this.value, this.children});
factory Child.fromJson(Map<String, dynamic> json) => Child(
label: json['label'] as String?,
value: json['value'] as String?,
children: (json['children'] as List<dynamic>?)
?.map((e) => Child.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> toJson() => {
'label': label,
'value': value,
'children': children?.map((e) => e.toJson()).toList(),
};
}
控制器中
assets/img/city.json
这里我只放出部分数据,可以通过后台获取完整数据,
只要是这个数据结构就行。(自己百度找下也有这个数据)
[{
"label": "北京市",
"value": "110000",
"children": [{
"label": "市辖区",
"value": "110100",
"children": [
{ "label": "东城区", "value": "110101" },
{ "label": "西城区", "value": "110102" },
{ "label": "朝阳区", "value": "110105" },
{ "label": "丰台区", "value": "110106" },
{ "label": "石景山区", "value": "110107" },
{ "label": "海淀区", "value": "110108" },
{ "label": "门头沟区", "value": "110109" },
{ "label": "房山区", "value": "110111" },
{ "label": "通州区", "value": "110112" },
{ "label": "顺义区", "value": "110113" },
{ "label": "昌平区", "value": "110114" },
{ "label": "大兴区", "value": "110115" },
{ "label": "怀柔区", "value": "110116" },
{ "label": "平谷区", "value": "110117" },
{ "label": "密云区", "value": "110118" },
{ "label": "延庆区", "value": "110119"}
]
}]
},
{
"label": "天津市",
"value": "120000",
"children": [{
"label": "市辖区",
"value": "120100",
"children": [
{ "label": "和平区", "value": "120101" },
{ "label": "河东区", "value": "120102" },
{ "label": "河西区", "value": "120103" },
{ "label": "南开区", "value": "120104" },
{ "label": "河北区", "value": "120105" },
{ "label": "红桥区", "value": "120106" },
{ "label": "东丽区", "value": "120110" },
{ "label": "西青区", "value": "120111" },
{ "label": "津南区", "value": "120112" },
{ "label": "北辰区", "value": "120113" },
{ "label": "武清区", "value": "120114" },
{ "label": "宝坻区", "value": "120115" },
{ "label": "滨海新区", "value": "120116" },
{ "label": "宁河区", "value": "120117" },
{ "label": "静海区", "value": "120118" },
{"label": "蓟州区", "value": "120119"}
]
}]
},
]
更多示例:除了省市区三级联动,可以返回其他数据,实现联动