custom_check_box.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import 'package:cs_resources/constants/color_constants.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:cs_resources/theme/app_colors_theme.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:shared/utils/log_utils.dart';
  6. import 'package:widgets/ext/ex_widget.dart';
  7. import 'package:widgets/my_load_image.dart';
  8. import 'package:widgets/my_text_view.dart';
  9. class CustomCheckBox extends StatefulWidget {
  10. final List<String> options;
  11. final Function(List<int> selectedIndexes) onOptionsSelected; // 选中项的索引回调
  12. final List<String> selectedOptions; // 已选中的选项列表
  13. final Color textColor;
  14. const CustomCheckBox({
  15. super.key,
  16. required this.options,
  17. required this.onOptionsSelected,
  18. required this.selectedOptions,
  19. this.textColor = Colors.white, // 默认可用
  20. });
  21. @override
  22. _CustomCheckBoxState createState() => _CustomCheckBoxState();
  23. }
  24. class _CustomCheckBoxState extends State<CustomCheckBox> {
  25. late List<String> _selectedOptions;
  26. late List<int> _selectedIndexes;
  27. @override
  28. void initState() {
  29. super.initState();
  30. _initializeSelectedOptions();
  31. }
  32. void _initializeSelectedOptions() {
  33. _selectedOptions = List.from(widget.selectedOptions);
  34. _selectedIndexes =
  35. widget.options.asMap().entries.where((entry) => _selectedOptions.contains(entry.value)).map((entry) => entry.key).toList(); // 根据选项匹配初始化索引
  36. }
  37. @override
  38. void didUpdateWidget(CustomCheckBox oldWidget) {
  39. super.didUpdateWidget(oldWidget);
  40. Log.d("oldWidget - selectedOptions :${oldWidget.selectedOptions} newWidget - selectedOptions:${widget.selectedOptions} ");
  41. // 使用ListEquality来比较两个列表的内容
  42. if (!_listEquals(oldWidget.selectedOptions, widget.selectedOptions)) {
  43. _initializeSelectedOptions();
  44. }
  45. }
  46. bool _listEquals(List<String> list1, List<String> list2) {
  47. if (list1.length != list2.length) {
  48. return false;
  49. }
  50. for (int i = 0; i < list1.length; i++) {
  51. if (list1[i] != list2[i]) {
  52. return false;
  53. }
  54. }
  55. return true;
  56. }
  57. @override
  58. Widget build(BuildContext context) {
  59. return Wrap(
  60. spacing: 15.0,
  61. runSpacing: 15.0,
  62. children: widget.options.asMap().entries.map((entry) {
  63. int index = entry.key;
  64. String option = entry.value;
  65. return _buildCheckBoxWithIconAndText(
  66. path: _selectedIndexes.contains(index) ? Assets.baseServiceCheckBoxChecked : Assets.baseServiceCheckBoxUncheck,
  67. iconColor: _selectedIndexes.contains(index) ? context.appColors.textPrimary : Colors.transparent,
  68. text: option,
  69. value: _selectedIndexes.contains(index),
  70. onChanged: (isChecked) {
  71. setState(() {
  72. if (isChecked) {
  73. if (!_selectedOptions.contains(option)) {
  74. _selectedOptions.add(option);
  75. _selectedIndexes.add(index);
  76. }
  77. } else {
  78. _selectedOptions.remove(option);
  79. _selectedIndexes.remove(index);
  80. }
  81. widget.onOptionsSelected(_selectedIndexes);
  82. });
  83. },
  84. );
  85. }).toList(),
  86. );
  87. }
  88. Widget _buildCheckBoxWithIconAndText({
  89. required String path,
  90. Color? iconColor,
  91. required String text,
  92. required bool value,
  93. required Function(bool) onChanged,
  94. }) {
  95. return Row(
  96. mainAxisSize: MainAxisSize.min,
  97. children: <Widget>[
  98. MyAssetImage(
  99. path,
  100. color: iconColor,
  101. width: 15.5,
  102. height: 15.5,
  103. ),
  104. const SizedBox(width: 10),
  105. MyTextView(
  106. text,
  107. textColor: widget.textColor,
  108. fontSize: 14,
  109. isFontRegular: true,
  110. ),
  111. ],
  112. ).onTap(() {
  113. onChanged(!value); // 点击时切换选中状态
  114. });
  115. }
  116. }