dialog_check.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/components/alert_dialog.dart';
  4. class VDialogCheck<T, TValue> extends StatefulWidget {
  5. const VDialogCheck({
  6. Key? key,
  7. this.title,
  8. required this.source,
  9. required this.initialValue,
  10. this.labelGetter,
  11. required this.valueGetter,
  12. // ignore: non_constant_identifier_names
  13. this.MutexValue,
  14. }) : super(key: key);
  15. final String? title;
  16. final List<T> source;
  17. final List<TValue> initialValue;
  18. // ignore: non_constant_identifier_names
  19. final TValue? MutexValue;
  20. /// 选项文本提取函数
  21. final String Function(T data)? labelGetter;
  22. /// 选项值提取函数
  23. final TValue Function(T data) valueGetter;
  24. @override
  25. // ignore: library_private_types_in_public_api
  26. _VDialogCheckState<T, TValue> createState() =>
  27. _VDialogCheckState<T, TValue>();
  28. Future<T?> show<T>() => VAlertDialog.showDialog<T>(this);
  29. }
  30. class _VDialogCheckState<T, TValue> extends State<VDialogCheck<T, TValue>> {
  31. List<TValue> initialValue = [];
  32. @override
  33. void initState() {
  34. super.initState();
  35. initialValue = widget.initialValue.toList();
  36. }
  37. @override
  38. Widget build(BuildContext context) {
  39. return VAlertDialog(
  40. width: 460,
  41. title: widget.title,
  42. content: Scrollbar(
  43. thumbVisibility: true,
  44. child: SingleChildScrollView(
  45. child: Column(
  46. mainAxisSize: MainAxisSize.min,
  47. children: _buildOptions(context),
  48. ),
  49. ),
  50. ),
  51. onConfirm: () {
  52. Get.back(result: initialValue);
  53. },
  54. );
  55. }
  56. List<Widget> _buildOptions(BuildContext context) {
  57. final primaryColor = Theme.of(context).primaryColor;
  58. final children = <Widget>[];
  59. for (var i = 0; i < widget.source.length; i++) {
  60. final data = widget.source[i];
  61. final val = widget.valueGetter(data);
  62. final isSelected = initialValue.contains(val);
  63. Widget label;
  64. label = Text(
  65. widget.labelGetter!(data),
  66. style: TextStyle(
  67. color: isSelected ? primaryColor : Colors.black,
  68. fontSize: 20,
  69. ),
  70. );
  71. final widgetItem = Container(
  72. alignment: Alignment.centerLeft,
  73. height: 56,
  74. padding: const EdgeInsets.symmetric(horizontal: 8),
  75. color: isSelected ? Theme.of(context).secondaryHeaderColor : null,
  76. child: Row(
  77. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  78. children: [
  79. Row(
  80. mainAxisSize: MainAxisSize.min,
  81. children: [
  82. const SizedBox(
  83. width: 20,
  84. ),
  85. label
  86. ],
  87. ),
  88. if (isSelected)
  89. Row(
  90. children: [
  91. Icon(
  92. Icons.check,
  93. size: 24,
  94. color: primaryColor,
  95. ),
  96. const SizedBox(
  97. width: 20,
  98. )
  99. ],
  100. )
  101. ],
  102. ),
  103. );
  104. children.add(
  105. Material(
  106. color: Colors.transparent,
  107. child: Ink(
  108. child: InkWell(
  109. onTap: () {
  110. final val = widget.valueGetter(data);
  111. // if (!(widget.MutexValue != null &&
  112. // initialValue.contains(widget.MutexValue)) ||
  113. // val == widget.MutexValue) {
  114. setState(() {
  115. if ((val == widget.MutexValue &&
  116. !initialValue.contains(widget.MutexValue))) {
  117. initialValue.clear();
  118. }
  119. if (val != widget.MutexValue &&
  120. initialValue.contains(widget.MutexValue)) {
  121. initialValue.remove(widget.MutexValue);
  122. }
  123. if (initialValue.contains(val)) {
  124. initialValue.remove(val);
  125. } else {
  126. initialValue.add(val);
  127. }
  128. });
  129. // }
  130. },
  131. child: widgetItem,
  132. )),
  133. ),
  134. );
  135. }
  136. return children;
  137. }
  138. }