import 'package:flutter/material.dart'; /// 多选框组 class VCheckBoxGroup 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? itemSpace; const VCheckBoxGroup({ super.key, required this.source, this.values, required this.labelGetter, required this.valueGetter, this.onChanged, this.itemSpace, }); @override State createState() => _VCheckBoxGroupState(); } class _VCheckBoxGroupState extends State> { late List _checkedValues; @override void initState() { _checkedValues = widget.values ?? []; 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]; children.add( VCheckBox( label: widget.labelGetter(e), isChecked: false, onChanged: (value) { _onItemChanged(e, value); }, ), ); if (i < length - 1) { children.add(SizedBox(width: widget.itemSpace)); } } // return Flow( // delegate: FlowlayoutDelegate(), // children: children, // ); return Row( mainAxisSize: MainAxisSize.min, children: children, ); } void _onItemChanged(T data, bool isChecked) { final value = widget.valueGetter(data); if (isChecked) { if (_checkedValues.contains(value) == false) { _checkedValues.add(value); } } else { _checkedValues.remove(value); } widget.onChanged?.call(_checkedValues); } } /// 多选框 class VCheckBox extends StatefulWidget { /// 文本 final String label; /// 是否默认选中 final bool? isChecked; /// 选中状态变更 final ValueChanged? onChanged; const VCheckBox({ 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) { return Material( child: Ink( child: InkWell( onTap: () { setState(() { _isChecked = !_isChecked; widget.onChanged?.call(_isChecked); }); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), alignment: Alignment.center, child: Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ _CheckStatusTag(isChecked: _isChecked), const SizedBox(width: 6), Text( widget.label, style: const TextStyle(color: Colors.black, fontSize: 16), ), ], ), ), ), ), ); } } class _CheckStatusTag extends StatelessWidget { final bool isChecked; const _CheckStatusTag({super.key, required this.isChecked}); @override Widget build(BuildContext context) { final color = Theme.of(context).primaryColor; return Container( alignment: Alignment.center, width: 18, height: 18, decoration: BoxDecoration( color: isChecked ? color : Colors.white, border: Border.all(width: 1, color: color), borderRadius: BorderRadius.zero, // boxShadow: [], ), child: isChecked ? const Icon(Icons.check, size: 16, color: Colors.white) : null, ); } }