import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'cell.dart'; typedef VRadioCellGroupItemBuilder = Widget Function(T data); typedef VRadioCellGroupCheckChanged = void Function( TValue value, bool isChecked, T data, TValue? checkedValue, ); class RadioCellGroupItem { final T data; final bool isChecked; final bool isDisabled; RadioCellGroupItem( this.data, { this.isChecked = false, this.isDisabled = false, }); } class VRadioCellGroup extends StatefulWidget { final List> source; /// 选项文本提取函数 final String Function(T data) labelGetter; /// 选项值提取函数 final TValue Function(T data) valueGetter; final VRadioCellGroupCheckChanged? onChanged; final bool isScrollable; final ScrollController? controller; const VRadioCellGroup({ super.key, required this.source, required this.labelGetter, required this.valueGetter, this.onChanged, this.isScrollable = true, this.controller, }); @override State createState() => _VRadioCellGroupState(); } class _VRadioCellGroupState extends State> { TValue? _checkedValue; @override void initState() { T? data = widget.source.firstWhereOrNull((e) => e.isChecked)?.data; if (data != null) { _checkedValue = widget.valueGetter.call(data); } 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(RadioCellGroupItem item) { final label = widget.labelGetter.call(item.data); final value = widget.valueGetter.call(item.data); final isChecked = _checkedValue == value; return VRadioCell( 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) { _checkedValue = value; } else { _checkedValue = null; } widget.onChanged?.call(value, isChecked, data, _checkedValue); }); } }