import 'package:flutter/material.dart'; ///按钮式单选框组 class VSelectBoxButtonGroup extends StatefulWidget { final List source; final TValue? value; final String Function(T data) labelGetter; final TValue Function(T data) valueGetter; final ValueChanged? onChanged; final double? itemWidth; const VSelectBoxButtonGroup({ super.key, required this.source, this.value, required this.labelGetter, required this.valueGetter, this.onChanged, this.itemWidth, }); @override State createState() => _VSelectBoxGroupState(); } class _VSelectBoxGroupState extends State> { late TValue? _selectedValue; @override void initState() { _selectedValue = widget.value; super.initState(); } @override Widget build(BuildContext context) { final children = []; final length = widget.source.length; for (var i = 0; i < length; i++) { final e = widget.source[i]; final value = widget.valueGetter(e); final isSelect = _selectedValue == value; children.add(VSelectBoxButton( // key: UniqueKey(), label: widget.labelGetter(e), isSelected: isSelect, onChanged: (status) { setState(() { if (status) { _onChanged(value); } else { _onChanged(null); } }); })); } return Wrap( spacing: 12, runSpacing: 8, children: children, ); } void _onChanged(TValue? value) { _selectedValue = value; widget.onChanged?.call(_selectedValue); } } class VSelectBoxButton extends StatefulWidget { final String label; final bool? isSelected; final ValueChanged? onChanged; const VSelectBoxButton( {super.key, required this.label, this.isSelected, required this.onChanged}); @override State createState() => _VSelectBoxState(); } class _VSelectBoxState extends State { bool _isSelected = false; @override void initState() { if (widget.isSelected != null) { _isSelected = widget.isSelected!; } super.initState(); } @override void didUpdateWidget(covariant VSelectBoxButton oldWidget) { _isSelected=widget.isSelected==true; super.didUpdateWidget(oldWidget); } @override Widget build(BuildContext context) { const height = 56.0; const borderRadius = height / 2; final primaryColor = Theme.of(context).primaryColor; return Material( child: Ink( child: InkWell( borderRadius: BorderRadius.circular(borderRadius), onTap: () { setState( () { _isSelected = !_isSelected; widget.onChanged?.call(_isSelected); }, ); }, child: Container( padding: const EdgeInsets.only(left: 0, right: borderRadius), alignment: Alignment.center, height: height, decoration: BoxDecoration( color: _isSelected ? primaryColor : Colors.white, borderRadius: BorderRadius.circular(borderRadius), border: _isSelected ? null : Border.all(color: primaryColor), ), child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ if (_isSelected) ...[ const Icon( Icons.check_rounded, color: Colors.green, size: 24, ), const SizedBox( width: 8, ), ], if (!_isSelected) const SizedBox( width: 32, ), Text( widget.label, style: TextStyle( color: _isSelected ? Colors.white : primaryColor, fontSize: 20), ) ], ), ), ), ), ); } }