qhdkfq_regulatory_flutter/lib/home/department_picker.dart

141 lines
4.1 KiB
Dart
Raw Permalink Normal View History

2025-07-09 14:31:12 +08:00
import 'package:flutter/material.dart';
2025-07-11 11:01:27 +08:00
import '../models/department_category.dart';
2025-07-09 14:31:12 +08:00
class DepartmentPicker extends StatefulWidget {
2025-07-11 11:01:27 +08:00
final List<DepartmentCategory> data;
2025-07-09 14:31:12 +08:00
final String? initialSelectedId;
final Set<String>? initialExpandedSet;
final ValueChanged<String?> onSelected;
const DepartmentPicker({
Key? key,
required this.data,
this.initialSelectedId,
this.initialExpandedSet,
required this.onSelected,
}) : super(key: key);
@override
_DepartmentPickerState createState() => _DepartmentPickerState();
}
class _DepartmentPickerState extends State<DepartmentPicker> {
late String? selectedId;
late Set<String> expandedSet;
@override
void initState() {
super.initState();
selectedId = widget.initialSelectedId;
expandedSet = Set<String>.from(widget.initialExpandedSet ?? {});
}
2025-07-11 11:01:27 +08:00
Widget _buildRow(DepartmentCategory cat, int indent) {
2025-07-09 14:31:12 +08:00
final bool hasChildren = cat.children.isNotEmpty;
final bool isExpanded = expandedSet.contains(cat.id);
final bool isSelected = cat.id == selectedId;
return Column(
children: [
InkWell(
onTap: () {
setState(() {
if (hasChildren) {
2025-07-11 11:01:27 +08:00
isExpanded
? expandedSet.remove(cat.id)
: expandedSet.add(cat.id);
2025-07-09 14:31:12 +08:00
}
selectedId = cat.id;
});
},
child: Container(
color: Colors.white,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 16.0 * indent),
SizedBox(
width: 24,
child: hasChildren
? Icon(
2025-07-11 11:01:27 +08:00
isExpanded
? Icons.arrow_drop_down
: Icons.arrow_right_outlined,
2025-07-09 14:31:12 +08:00
size: 30,
color: Colors.grey[600],
)
: const SizedBox.shrink(),
),
const SizedBox(width: 8),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Text(cat.title),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Icon(
isSelected
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
color: Colors.blue,
),
),
],
),
),
),
2025-07-11 11:01:27 +08:00
2025-07-09 14:31:12 +08:00
if (hasChildren && isExpanded)
2025-07-11 11:01:27 +08:00
...cat.children
.map((c) => _buildRow(c, indent + 1)),
2025-07-09 14:31:12 +08:00
],
);
}
2025-07-11 11:01:27 +08:00
2025-07-09 14:31:12 +08:00
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.7,
color: Colors.transparent,
child: Column(
children: [
// 顶部操作栏
Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: const Text('取消', style: TextStyle(fontSize: 16)),
),
GestureDetector(
onTap: () => Navigator.of(context).pop(selectedId),
child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.blue),),
),
],
),
),
const Divider(height: 1),
// 列表区
Expanded(
child: Container(
color: Colors.white,
child: ListView.builder(
itemCount: widget.data.length,
itemBuilder: (ctx, idx) => _buildRow(widget.data[idx], 0),
),
),
),
],
),
);
}
}