measure_images_bar.dart 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import 'package:fis_jsonrpc/rpc.dart';
  2. import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
  3. import 'package:fis_measure/process/workspace/measure_controller.dart';
  4. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  5. import 'package:fis_measure/process/workspace/measure_handler.dart';
  6. import 'package:fis_measure/view/measure/measure_images_bar.dart';
  7. export 'package:fis_lib_business_components/index.dart';
  8. import 'package:fis_ui/index.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:get/get.dart';
  11. class MeasureImagesBar extends StatefulWidget implements FWidget {
  12. const MeasureImagesBar({Key? key}) : super(key: key);
  13. @override
  14. State<MeasureImagesBar> createState() => _MeasureImagesBarState();
  15. }
  16. class _MeasureImagesBarState extends State<MeasureImagesBar> {
  17. /// 图片滑动控制器
  18. ScrollController scrollController = ScrollController();
  19. /// 数据
  20. final measureData = Get.find<MeasureDataController>();
  21. /// 全部图片list
  22. final measureController = Get.find<MeasureController>();
  23. /// 当前可滑动的范围宽度
  24. late double width = 0;
  25. /// 是否滑到最后
  26. bool _isEnd = false;
  27. /// 计算下标
  28. int _currentIndex = 0;
  29. /// 左边能否滑动
  30. bool get isLeftCanScroll => _currentIndex <= 0;
  31. /// 右边能否滑动
  32. bool get isRightCanScroll => _isEnd;
  33. /// 滑动区域的key值
  34. final GlobalKey globalKey = GlobalKey();
  35. /// 图片左划事件
  36. void onLeftMoveImage() async {
  37. if (_currentIndex > 0) {
  38. _currentIndex--;
  39. await scrollController.animateTo(
  40. (160 * _currentIndex).toDouble(),
  41. duration: const Duration(milliseconds: 300),
  42. curve: Curves.linear,
  43. );
  44. }
  45. }
  46. /// 图片右划事件
  47. void onRightMoveImage() async {
  48. if (!isRightCanScroll) {
  49. _currentIndex++;
  50. await scrollController.animateTo(
  51. (160 * _currentIndex).toDouble(),
  52. duration: const Duration(milliseconds: 300),
  53. curve: Curves.linear,
  54. );
  55. }
  56. }
  57. @override
  58. Widget build(BuildContext context) {
  59. return FContainer(
  60. height: 120,
  61. margin: const EdgeInsets.symmetric(
  62. vertical: 15,
  63. ),
  64. child: FRow(
  65. children: [
  66. _buildImageListIcon(
  67. FIcons.fis_left_arrow,
  68. isLeftCanScroll,
  69. onLeftMoveImage,
  70. ),
  71. FExpanded(
  72. child: LeftSiderImageList(
  73. scrollController: scrollController,
  74. globalKey: globalKey,
  75. remedicalList: measureData.remedicalList,
  76. ),
  77. ),
  78. _buildImageListIcon(
  79. FIcons.fis_right_arrow,
  80. isRightCanScroll,
  81. onRightMoveImage,
  82. ),
  83. ],
  84. ),
  85. );
  86. }
  87. @override
  88. void initState() {
  89. scrollController.addListener(
  90. () async {
  91. // 如果滑动到最右边
  92. if (scrollController.position.pixels ==
  93. scrollController.position.maxScrollExtent) {
  94. setState(() {
  95. _isEnd = true;
  96. });
  97. } else {
  98. setState(
  99. () {
  100. _isEnd = false;
  101. },
  102. );
  103. }
  104. },
  105. );
  106. super.initState();
  107. }
  108. @override
  109. void didChangeDependencies() {
  110. super.didChangeDependencies();
  111. WidgetsBinding.instance.addPostFrameCallback(
  112. (mag) {
  113. width = globalKey.currentContext!.size!.width;
  114. setState(
  115. () {
  116. _isEnd = width >= measureData.remedicalList.length * 160;
  117. _currentIndex = measureController.examInfo.selectedImageIndex;
  118. if (_currentIndex * 160 >
  119. scrollController.position.maxScrollExtent) {
  120. _currentIndex = scrollController.position.maxScrollExtent ~/ 160;
  121. }
  122. scrollController.animateTo(
  123. (160 * _currentIndex).toDouble(),
  124. duration: const Duration(milliseconds: 300),
  125. curve: Curves.linear,
  126. );
  127. },
  128. );
  129. },
  130. );
  131. }
  132. @override
  133. void dispose() {
  134. super.dispose();
  135. }
  136. FWidget _buildImageListIcon(
  137. IconData iconsData, bool isCanClick, Function onIconTap) {
  138. return FInkWell(
  139. onTap: () => onIconTap.call(),
  140. child: FContainer(
  141. width: 100,
  142. child: FIcon(
  143. iconsData,
  144. color: isCanClick ? Colors.grey : Colors.white,
  145. size: 30,
  146. ),
  147. ),
  148. );
  149. }
  150. }
  151. /// 当前测量组的所有图片
  152. class LeftSiderImageList extends StatefulWidget implements FWidget {
  153. const LeftSiderImageList({
  154. required this.scrollController,
  155. required this.globalKey,
  156. required this.remedicalList,
  157. Key? key,
  158. }) : super(key: key);
  159. /// 图片滑动控制器
  160. final ScrollController scrollController;
  161. final GlobalKey globalKey;
  162. final List<RemedicalInfoDTO> remedicalList;
  163. @override
  164. State<LeftSiderImageList> createState() => _LeftSiderImageListState();
  165. }
  166. class _LeftSiderImageListState extends State<LeftSiderImageList> {
  167. /// 当前测量的图片
  168. // final measureCurrentImage = Get.put(MeasureGetCurrentImage());
  169. /// 测量AI数据
  170. final measureData = Get.find<MeasureDataController>();
  171. late final measureController = Get.find<MeasureController>();
  172. late final measureHandler = Get.put(MeasureHandler());
  173. int selectedImageIndex = -1;
  174. /// 获取图片地址
  175. void onChangeImage(
  176. String imageUrl,
  177. String remedicalCode,
  178. ) async {
  179. if (measureData.itemCurrentImage == imageUrl) {
  180. return;
  181. }
  182. measureHandler.changeImageLoaded = true;
  183. measureHandler.imageChanged = ChangeImageInfo(
  184. imageUrl,
  185. remedicalCode,
  186. );
  187. ExamImageInfo selectedImage = measureController.examInfo.images.firstWhere(
  188. (element) => element.url == imageUrl,
  189. );
  190. selectedImageIndex =
  191. measureController.examInfo.images.indexOf(selectedImage);
  192. measureData.itemCurrentImage = imageUrl;
  193. measureController.examInfo.selectedImageIndex = selectedImageIndex;
  194. setState(() {});
  195. }
  196. @override
  197. void initState() {
  198. super.initState();
  199. }
  200. @override
  201. void dispose() {
  202. super.dispose();
  203. }
  204. @override
  205. FWidget build(BuildContext context) {
  206. return FContainer(
  207. key: ValueKey(measureData.itemCurrentImage),
  208. alignment: Alignment.topCenter,
  209. child: _buildImageList(widget.remedicalList),
  210. );
  211. }
  212. FWidget _buildImageList(List<RemedicalInfoDTO> remedicalItemList) {
  213. return FContainer(
  214. key: widget.globalKey,
  215. child: FListView.builder(
  216. scrollDirection: Axis.horizontal,
  217. shrinkWrap: true,
  218. controller: widget.scrollController,
  219. itemCount: remedicalItemList.toList().length,
  220. itemBuilder: (BuildContext context, int index) {
  221. final FWidget image = ContentImage(
  222. remedicalInfo: remedicalItemList[index],
  223. fileDataType: remedicalItemList[index].fileDataType,
  224. terminalImage: TerminalImage(
  225. previewUrl: remedicalItemList[index].terminalImages!.previewUrl,
  226. ),
  227. isMeasure: true,
  228. onTap: () => onChangeImage(
  229. remedicalItemList[index].terminalImages!.imageUrl!,
  230. remedicalItemList[index].remedicalCode!,
  231. ),
  232. );
  233. return FContainer(
  234. key: ValueKey(measureData.itemCurrentImage),
  235. width: 160,
  236. alignment: Alignment.center,
  237. decoration: BoxDecoration(
  238. border: Border.all(
  239. width: 3,
  240. color: remedicalItemList[index].terminalImages!.imageUrl! !=
  241. measureData.itemCurrentImage
  242. ? Colors.grey
  243. : Colors.blue,
  244. ),
  245. ),
  246. child: image,
  247. );
  248. },
  249. ),
  250. );
  251. }
  252. }