multi_selected.dart 7.8 KB

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