custom_radio_check.dart 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import 'package:cs_resources/constants/color_constants.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:widgets/my_load_image.dart';
  5. import 'package:widgets/my_text_view.dart';
  6. import '../ext/ex_widget.dart';
  7. /*
  8. * 条件单选 Radio
  9. */
  10. class CustomRadioCheck extends StatefulWidget {
  11. final List<String> options;
  12. int? selectedPosition;
  13. final Function(int index, String text) onOptionSelected;
  14. final bool enable;
  15. final Color textColor;
  16. CustomRadioCheck({
  17. required this.options,
  18. required this.onOptionSelected,
  19. this.selectedPosition = 0,
  20. this.enable = true, // 默认可用
  21. this.textColor = Colors.white, // 默认可用
  22. });
  23. @override
  24. _CustomRadioCheckState createState() => _CustomRadioCheckState();
  25. }
  26. class _CustomRadioCheckState extends State<CustomRadioCheck> {
  27. String? _selectedOption;
  28. @override
  29. void initState() {
  30. super.initState();
  31. _initializeSelectedOption();
  32. }
  33. void _initializeSelectedOption() {
  34. if (widget.selectedPosition != null && widget.selectedPosition! >= 0 && widget.selectedPosition! < widget.options.length) {
  35. _selectedOption = widget.options[widget.selectedPosition!];
  36. } else {
  37. _selectedOption = widget.options.isNotEmpty ? widget.options[0] : null;
  38. }
  39. }
  40. @override
  41. void didUpdateWidget(CustomRadioCheck oldWidget) {
  42. super.didUpdateWidget(oldWidget);
  43. // 如果 selectedPosition 发生变化,重新初始化选中项
  44. if (oldWidget.selectedPosition != widget.selectedPosition) {
  45. _initializeSelectedOption();
  46. }
  47. }
  48. @override
  49. Widget build(BuildContext context) {
  50. return Wrap(
  51. spacing: 8.0,
  52. runSpacing: 8.0,
  53. children: widget.options.map((option) {
  54. return _buildRadioWithIconAndText(
  55. path: option == _selectedOption ? Assets.baseServiceRadioChecked : Assets.baseServiceRadioUncheck,
  56. text: option,
  57. value: option == _selectedOption,
  58. onChanged: widget.enable
  59. ? (value) {
  60. // 只在可用状态下响应点击
  61. setState(() {
  62. _selectedOption = option;
  63. int selectedIndex = widget.options.indexOf(option);
  64. widget.onOptionSelected(selectedIndex, option);
  65. });
  66. }
  67. : null, // 如果不可用则不设置回调
  68. );
  69. }).toList(),
  70. );
  71. }
  72. Widget _buildRadioWithIconAndText({
  73. required String path,
  74. required String text,
  75. required bool value,
  76. required Function(bool)? onChanged, // 允许 onChanged 为 null
  77. }) {
  78. return Row(
  79. mainAxisSize: MainAxisSize.min,
  80. children: <Widget>[
  81. MyAssetImage(path, width: 22, height: 22),
  82. const SizedBox(width: 10),
  83. MyTextView(
  84. text,
  85. textColor: widget.enable ? widget.textColor : ColorConstants.gray, // 根据 enable 改变文本颜色
  86. fontSize: 14,
  87. isFontRegular: true,
  88. ),
  89. ],
  90. ).marginOnly(right: 20, bottom: 5).onTap(() {
  91. if (onChanged != null) {
  92. // 只有在可用状态下才触发
  93. onChanged(true);
  94. }
  95. });
  96. }
  97. }