multi_selected.dart 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
  2. import 'package:fis_lib_report/converts/text_size_converter.dart';
  3. import 'package:fis_lib_report/pages/components/input_text.dart';
  4. import 'package:fis_lib_report/report/inputText.dart';
  5. import 'package:fis_lib_report/report/multiSelected.dart';
  6. import 'package:fis_lib_report/report/rt_color.dart';
  7. import 'package:fis_lib_report/report/singleSelected.dart';
  8. import 'package:fis_lib_report/report_info/multi_selected_info.dart';
  9. import 'package:fis_lib_report/report_info/report_info.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:dropdown_button2/dropdown_button2.dart';
  12. import 'package:fis_lib_report/report/inputText.dart';
  13. import 'package:fis_ui/simple/select.dart';
  14. class RMultiSelected extends StatefulWidget {
  15. final MultiSelected multiSelected;
  16. RMultiSelected(this.multiSelected);
  17. @override
  18. State<StatefulWidget> createState() {
  19. return _RRMultiSelectedState(multiSelected);
  20. }
  21. }
  22. class _RRMultiSelectedState extends State<RMultiSelected> {
  23. MultiSelected multiSelected;
  24. _RRMultiSelectedState(this.multiSelected);
  25. final String _value = '';
  26. String? _selectedItemView = '';
  27. List<String>? _items = [];
  28. final List<String>? _selectedItems = [];
  29. double _width = 0.0;
  30. MulitiSelectedInfo? _mulitiSelectedInfo;
  31. TextStyle _textStyle = TextStyle();
  32. @override
  33. initState() {
  34. final selectInfo = ReportInfo.instance.getElementInfo(multiSelected);
  35. if (selectInfo != null) {
  36. _mulitiSelectedInfo = selectInfo as MulitiSelectedInfo;
  37. }
  38. if (multiSelected.items!.isNotEmpty) {
  39. _items = multiSelected.items;
  40. }
  41. _width = PtToPxConverter.ptToPx(multiSelected.lineWidth);
  42. final fontColor = multiSelected.fontColor ?? RTColor.Black;
  43. _textStyle = TextStyle(
  44. color: Color.fromARGB(
  45. fontColor.a!, fontColor.r!, fontColor.g!, fontColor.b!),
  46. fontSize: PtToPxConverter.ptToPx(multiSelected.fontSize),
  47. );
  48. super.initState();
  49. }
  50. @override
  51. Widget build(BuildContext context) {
  52. final background = multiSelected.background ?? RTColor(255, 255, 255, 255);
  53. return Stack(
  54. children: [
  55. Container(
  56. decoration: BoxDecoration(
  57. border: Border.all(color: Colors.grey, width: 1.0),
  58. borderRadius: BorderRadius.circular(0),
  59. color: Color.fromARGB(
  60. background.a!, background.r!, background.g!, background.b!),
  61. ),
  62. padding: const EdgeInsets.only(right: 25),
  63. width: _width,
  64. height: 22,
  65. child: Text(
  66. _selectedItemView!,
  67. maxLines: 1,
  68. style: _textStyle,
  69. ),
  70. ),
  71. _buildDropdownButton(),
  72. ],
  73. );
  74. }
  75. List<DropdownMenuItem<String>> buildItems() {
  76. return _items!.map((String e) {
  77. final active = e == _value;
  78. return DropdownMenuItem<String>(
  79. child: _OptionRow(
  80. multiSelected,
  81. e,
  82. isActive: active,
  83. height: 22,
  84. onTap: () {
  85. setState(() {
  86. if (_selectedItems!.contains(e)) {
  87. _selectedItems!.remove(e);
  88. } else {
  89. _selectedItems!.add(e);
  90. }
  91. String text = '';
  92. for (var element in _selectedItems!) {
  93. final index = _selectedItems!.indexOf(element);
  94. if (index > 0) {
  95. text = text + ',' + element;
  96. } else if (index == 0) {
  97. text = element;
  98. } else if (_selectedItems!.isEmpty) {
  99. text = '';
  100. }
  101. }
  102. _selectedItemView = text;
  103. final width = TextSizeConvert.getTextSize(text, _textStyle).width;
  104. if (_width < width - 25) {
  105. // _width = width - 25;
  106. }
  107. });
  108. if (_mulitiSelectedInfo != null) {
  109. _mulitiSelectedInfo!.selectedItems = _selectedItems;
  110. }
  111. },
  112. isSelected: _selectedItems!.contains(e),
  113. ),
  114. value: e,
  115. );
  116. }).toList();
  117. }
  118. Widget _buildDropdownButton() {
  119. if (_items!.isEmpty) {
  120. return const SizedBox();
  121. }
  122. var buttonDecoration = BoxDecoration(
  123. border: Border.all(color: Colors.transparent, width: 1.0),
  124. borderRadius: BorderRadius.circular(0),
  125. color: Colors.transparent,
  126. );
  127. return SizedBox(
  128. height: 22,
  129. width: _width,
  130. child: DropdownButtonHideUnderline(
  131. child: DropdownButton2<String>(
  132. dropdownMaxHeight: 300,
  133. buttonWidth: _width,
  134. itemPadding: const EdgeInsets.symmetric(horizontal: 1, vertical: 2),
  135. itemHeight: 28,
  136. // itemPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
  137. isExpanded: false,
  138. dropdownOverButton: false,
  139. scrollbarAlwaysShow: true,
  140. scrollbarThickness: 4,
  141. scrollbarRadius: const Radius.circular(2),
  142. buttonPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 0),
  143. dropdownDecoration: BoxDecoration(
  144. borderRadius: BorderRadius.circular(4),
  145. ),
  146. buttonDecoration: buttonDecoration,
  147. offset: const Offset(0, -4),
  148. selectedItemHighlightColor: Theme.of(context).secondaryHeaderColor,
  149. selectedItemBuilder: (_) => _selectedItems!.map((e) {
  150. return SizedBox(
  151. width: _width - 34,
  152. child: Text(
  153. e,
  154. maxLines: 1,
  155. ),
  156. );
  157. }).toList(),
  158. value: null,
  159. items: buildItems(),
  160. onChanged: (v) {},
  161. ),
  162. ),
  163. );
  164. }
  165. }
  166. class _OptionRow extends StatefulWidget {
  167. _OptionRow(
  168. this.multiSelected,
  169. this.label, {
  170. Key? key,
  171. this.isActive = false,
  172. this.height,
  173. this.onTap,
  174. this.isSelected,
  175. }) : super(key: key);
  176. final Function? onTap;
  177. final MultiSelected multiSelected;
  178. final String label;
  179. final bool isActive;
  180. final double? height;
  181. bool? isSelected = false;
  182. @override
  183. State<StatefulWidget> createState() {
  184. return _OptionRowState(isSelected!);
  185. }
  186. }
  187. class _OptionRowState extends State<_OptionRow> {
  188. _OptionRowState(this.isSelected);
  189. bool? isSelected = false;
  190. @override
  191. Widget build(BuildContext context) {
  192. final color = widget.multiSelected.fontColor!;
  193. final background = widget.multiSelected.background!;
  194. final text = Text(
  195. widget.label,
  196. style: TextStyle(
  197. backgroundColor: Color.fromARGB(
  198. background.a!, background.r!, background.g!, background.b!),
  199. fontSize: PtToPxConverter.ptToPx(widget.multiSelected.fontSize),
  200. color: Color.fromARGB(color.a!, color.r!, color.g!, color.b!),
  201. ),
  202. );
  203. if (widget.height != null) {
  204. return GestureDetector(
  205. onTap: () {
  206. setState(() {
  207. isSelected = !isSelected!;
  208. });
  209. if (widget.onTap != null) {
  210. widget.onTap!.call();
  211. }
  212. },
  213. child: Container(
  214. color: Colors.white,
  215. alignment: Alignment.centerLeft,
  216. height: widget.height,
  217. width: PtToPxConverter.ptToPx(widget.multiSelected.lineWidth) - 34,
  218. child: Row(
  219. children: [
  220. Checkbox(
  221. onChanged: (bool? value) {
  222. setState(() {
  223. isSelected = value ?? false;
  224. });
  225. if (widget.onTap != null) {
  226. widget.onTap!.call();
  227. }
  228. },
  229. value: isSelected,
  230. ),
  231. Expanded(child: text),
  232. ],
  233. ),
  234. ),
  235. );
  236. } else {
  237. return text;
  238. }
  239. }
  240. }