123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import 'package:flutter/material.dart';
- ///按钮式单选框组
- class VSelectBoxButtonGroup<T, TValue> extends StatefulWidget {
- final List<T> source;
- final TValue? value;
- final String Function(T data) labelGetter;
- final TValue Function(T data) valueGetter;
- final ValueChanged<TValue?>? 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<StatefulWidget> createState() => _VSelectBoxGroupState<T, TValue>();
- }
- class _VSelectBoxGroupState<T, TValue>
- extends State<VSelectBoxButtonGroup<T, TValue>> {
- late TValue? _selectedValue;
- @override
- void initState() {
- _selectedValue = widget.value;
- super.initState();
- }
- @override
- Widget build(BuildContext context) {
- final children = <Widget>[];
- 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<bool>? onChanged;
- const VSelectBoxButton(
- {super.key,
- required this.label,
- this.isSelected,
- required this.onChanged});
- @override
- State<StatefulWidget> createState() => _VSelectBoxState();
- }
- class _VSelectBoxState extends State<VSelectBoxButton> {
- 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),
- )
- ],
- ),
- ),
- ),
- ),
- );
- }
- }
|