import 'package:flutter/material.dart'; import 'cell.dart'; typedef VCheckBoxCellGroupItemBuilder = Widget Function(T data); typedef VCheckBoxCellGroupCheckChanged = void Function( TValue value, bool isChecked, T data, List checkedValues, ); class CheckBoxCellGroupItem { final T data; final bool isChecked; final bool isDisabled; CheckBoxCellGroupItem( this.data, { this.isChecked = false, this.isDisabled = false, }); } class VCheckBoxCellGroup extends StatefulWidget { final List> source; /// 选项文本提取函数 final String Function(T data) labelGetter; /// 选项值提取函数 final TValue Function(T data) valueGetter; final VCheckBoxCellGroupCheckChanged? onChanged; final bool isScrollable; final ScrollController? controller; const VCheckBoxCellGroup({ super.key, required this.source, required this.labelGetter, required this.valueGetter, this.onChanged, this.isScrollable = true, this.controller, }); @override State createState() => _VCheckBoxCellGroupState(); } class _VCheckBoxCellGroupState extends State> { List _checkedValues = []; @override void initState() { _checkedValues = widget.source .where((e) => e.isChecked) .map((e) => widget.valueGetter.call(e.data)) .toList(); super.initState(); } @override Widget build(BuildContext context) { final divider = Divider( thickness: 1, color: Colors.grey.shade300, height: 2, ); final children = []; final count = widget.source.length; for (var i = 0; i < count; i++) { if (i > 0) { children.add(divider); } final item = widget.source[i]; children.add(_buildItemWidget(item)); } if (widget.isScrollable) { return ListView( shrinkWrap: true, controller: widget.controller ?? ScrollController(), children: children, ); } else { return Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: children, ); } } Widget _buildItemWidget(CheckBoxCellGroupItem item) { final label = widget.labelGetter.call(item.data); final value = widget.valueGetter.call(item.data); final isChecked = _checkedValues.contains(value); return VCheckBoxCell( label: label, value: value, isChecked: isChecked, isDisabled: item.isDisabled, onChanged: (_, isChecked) { _onCheckChanged(value, item.data, isChecked); }, ); } void _onCheckChanged(TValue value, T data, bool isChecked) { setState(() { if (isChecked) { if (_checkedValues.contains(value) == false) { _checkedValues.add(value); } } else { _checkedValues.remove(value); } widget.onChanged?.call(value, isChecked, data, _checkedValues); }); } }