import 'package:flutter/material.dart'; /// 按钮式多选框组 class VCheckBoxButtonGroup extends StatefulWidget { final List source; final List? values; final String Function(T data) labelGetter; final TValue Function(T data) valueGetter; final ValueChanged>? onChanged; final double? itemWidth; const VCheckBoxButtonGroup({ super.key, required this.source, this.values, required this.labelGetter, required this.valueGetter, this.onChanged, this.itemWidth, }); @override State createState() => _VCheckBoxGroupState(); } class _VCheckBoxGroupState extends State> { late List _checkedValues; @override void initState() { if (widget.values != null) { _checkedValues = List.from(widget.values!); } else { _checkedValues = []; } 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 isChecked = _checkedValues.contains(value); // children.add( // SizedBox( // width: widget.itemWidth ?? 160, // child: VCheckBoxButton( // label: widget.labelGetter(e), // isChecked: isChecked, // onChanged: (status) { // _onItemChanged(value, status); // }, // ), // ), // ); // TODO: children.add( VCheckBoxButton( label: widget.labelGetter(e), isChecked: isChecked, onChanged: (status) { _onItemChanged(value, status); }, ), ); } return Wrap( spacing: 12, runSpacing: 8, children: children, ); } void _onItemChanged(TValue value, bool isChecked) { if (isChecked) { if (_checkedValues.contains(value) == false) { _checkedValues.add(value); } } else { _checkedValues.remove(value); } widget.onChanged?.call(_checkedValues); } } /// 按钮式多选框 class VCheckBoxButton extends StatefulWidget { /// 文本 final String label; /// 是否默认选中 final bool? isChecked; /// 选中状态变更 final ValueChanged? onChanged; const VCheckBoxButton({ super.key, required this.label, this.isChecked, this.onChanged, }); @override State createState() => _VCheckBoxState(); } class _VCheckBoxState extends State { bool _isChecked = false; @override void initState() { if (widget.isChecked != null) { _isChecked = widget.isChecked!; } super.initState(); } @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(() { _isChecked = !_isChecked; widget.onChanged?.call(_isChecked); }); }, child: Container( padding: const EdgeInsets.only(left: 0, right: borderRadius), alignment: Alignment.center, height: height, // constraints: const BoxConstraints(minWidth: 160), decoration: BoxDecoration( color: _isChecked ? primaryColor : Colors.white, borderRadius: BorderRadius.circular(borderRadius), border: _isChecked ? null : Border.all(color: primaryColor), ), child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ if (_isChecked) ...[ const Icon( Icons.check_rounded, color: Colors.green, size: 24, ), const SizedBox(width: 8), ], if (!_isChecked) const SizedBox(width: 32), Text( widget.label, style: TextStyle( color: _isChecked ? Colors.white : primaryColor, fontSize: 20, ), ), ], ), ), ), ), ); } }