custom_check_box.dart 3.5 KB

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