import 'package:flutter/material.dart'; class Category { final String id; final String title; final List children; Category({ required this.id, required this.title, this.children = const [], }); } class DepartmentPicker extends StatefulWidget { final List data; final String? initialSelectedId; final Set? initialExpandedSet; final ValueChanged 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 { late String? selectedId; late Set expandedSet; @override void initState() { super.initState(); selectedId = widget.initialSelectedId; expandedSet = Set.from(widget.initialExpandedSet ?? {}); } Widget _buildRow(Category cat, int indent) { 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) { if (isExpanded) { expandedSet.remove(cat.id); } else { expandedSet.add(cat.id); } } 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( isExpanded ? Icons.expand_less : Icons.expand_more, size: 20, 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.green, ), ), ], ), ), ), if (hasChildren && isExpanded) ...cat.children.map((c) => _buildRow(c, indent + 1)), // const Divider(height: 1), ], ); } @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.green),), ), ], ), ), 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), ), ), ), ], ), ); } }