exam_body_weight.dart 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vnote_device_plugin/devices/weight.dart';
  4. import 'package:vnoteapp/components/alert_dialog.dart';
  5. import 'package:vnoteapp/components/button.dart';
  6. import 'package:vnoteapp/managers/interfaces/permission.dart';
  7. import 'package:vnoteapp/pages/check/models/form.dart';
  8. import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_card.dart';
  9. class ExamBodyWeight extends StatefulWidget {
  10. const ExamBodyWeight({
  11. super.key,
  12. required this.currentFormObject,
  13. required this.currentInputValue,
  14. this.specialInput,
  15. });
  16. final FormObject currentFormObject;
  17. final String currentInputValue;
  18. final Function(String value)? specialInput;
  19. @override
  20. State<ExamBodyWeight> createState() => _ExamBodyWeightState();
  21. }
  22. class _ExamBodyWeightState extends State<ExamBodyWeight> {
  23. var permissionManager = Get.find<IPermissionManager>();
  24. @override
  25. void initState() {
  26. permissionManager.requestLocationPermission();
  27. super.initState();
  28. }
  29. @override
  30. Widget build(BuildContext context) {
  31. return ExamCard(
  32. title: widget.currentFormObject.label ?? '',
  33. clickCard: () {
  34. _buildTempertureInput(widget.currentFormObject);
  35. },
  36. content: Container(
  37. alignment: Alignment.bottomRight,
  38. padding: const EdgeInsets.only(
  39. bottom: 20,
  40. right: 30,
  41. left: 40,
  42. ),
  43. constraints: const BoxConstraints(minHeight: 150),
  44. child: FittedBox(
  45. child: Row(
  46. mainAxisAlignment: MainAxisAlignment.end,
  47. crossAxisAlignment: CrossAxisAlignment.end,
  48. children: [
  49. RichText(
  50. text: TextSpan(
  51. text: widget.currentInputValue,
  52. style: const TextStyle(
  53. fontSize: 80,
  54. color: Colors.black,
  55. ),
  56. children: [
  57. TextSpan(
  58. text: widget.currentFormObject.append ?? '',
  59. style: const TextStyle(fontSize: 25),
  60. )
  61. ],
  62. ),
  63. ),
  64. ],
  65. ),
  66. ),
  67. ),
  68. );
  69. }
  70. Future<void> _buildTempertureInput(FormObject currentFormObject) async {
  71. // Future.delayed(const Duration(milliseconds: 3000), () {
  72. // specialInputController.text = generateRandomNumber().toString();
  73. // widget.specialInput?.call(specialInputController.text);
  74. // setState(() {});
  75. // });
  76. final result = await Get.dialog(
  77. Weight(
  78. currentFormObject: widget.currentFormObject,
  79. weight: widget.currentInputValue,
  80. ),
  81. barrierDismissible: false,
  82. );
  83. widget.specialInput?.call(result);
  84. print('object');
  85. print(result);
  86. print('object');
  87. }
  88. }
  89. class Weight extends StatefulWidget {
  90. const Weight({
  91. super.key,
  92. required this.currentFormObject,
  93. this.weight,
  94. });
  95. final FormObject currentFormObject;
  96. final String? weight;
  97. @override
  98. State<Weight> createState() => _WeightState();
  99. }
  100. class _WeightState extends State<Weight> {
  101. late final WeightDeviceWorker worker = WeightDeviceWorker(
  102. mac: 'CF:E4:2C:22:01:39',
  103. model: 'CF398BLE',
  104. );
  105. late TextEditingController specialInputController =
  106. TextEditingController(text: widget.weight ?? '00.0');
  107. bool connectFailState = false;
  108. bool connectSuccessState = false;
  109. bool isConnect = false;
  110. @override
  111. void initState() {
  112. connect();
  113. worker.successEvent.addListener(_onSuccess);
  114. worker.connectErrorEvent.addListener(_onConnectFail);
  115. worker.connectedEvent.addListener(_onConnectSuccess);
  116. super.initState();
  117. }
  118. Future<void> connect() async {
  119. connectFailState = false;
  120. isConnect = true;
  121. connectSuccessState = false;
  122. setState(() {});
  123. await worker.connect();
  124. }
  125. Future<void> disconnect() async {
  126. worker.connectErrorEvent.removeListener(_onConnectFail);
  127. worker.connectedEvent.removeListener(_onConnectSuccess);
  128. await worker.disconnect();
  129. }
  130. @override
  131. void dispose() {
  132. super.dispose();
  133. }
  134. void _onSuccess(_, double e) {
  135. setState(() {
  136. specialInputController.text = e.toString();
  137. // connectFailState = false;
  138. // connectSuccessState = false;
  139. isConnect = false;
  140. // disconnect();
  141. });
  142. }
  143. void _onConnectFail(sender, e) {
  144. print('连接设备失败');
  145. connectFailState = true;
  146. connectSuccessState = false;
  147. isConnect = false;
  148. disconnect();
  149. setState(() {});
  150. }
  151. void _onConnectSuccess(sender, e) {
  152. connectSuccessState = true;
  153. connectFailState = false;
  154. isConnect = false;
  155. setState(() {});
  156. }
  157. @override
  158. Widget build(BuildContext context) {
  159. return VAlertDialog(
  160. title: widget.currentFormObject.label ?? '',
  161. width: 600,
  162. contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
  163. content: buildMainWidget(),
  164. showCancel: true,
  165. onConfirm: () {
  166. disconnect();
  167. Get.back(result: specialInputController.text);
  168. },
  169. onCanceled: () {
  170. disconnect();
  171. },
  172. );
  173. }
  174. Widget buildInputField() {
  175. return Container(
  176. width: 350,
  177. padding: const EdgeInsets.only(left: 15),
  178. child: TextFormField(
  179. keyboardType: TextInputType.number,
  180. style: const TextStyle(
  181. fontSize: 100,
  182. ),
  183. showCursor: false,
  184. controller: specialInputController,
  185. decoration: const InputDecoration(
  186. labelStyle: TextStyle(
  187. fontSize: 100,
  188. ),
  189. ),
  190. ),
  191. );
  192. }
  193. Widget buildConnectFailText() {
  194. return const Text(
  195. '设备连接失败',
  196. style: TextStyle(
  197. color: Colors.red,
  198. fontSize: 25,
  199. ),
  200. textAlign: TextAlign.left,
  201. );
  202. }
  203. Widget buildConnectSuccessText() {
  204. return const Text(
  205. '设备连接成功',
  206. style: TextStyle(
  207. color: Colors.green,
  208. fontSize: 25,
  209. ),
  210. textAlign: TextAlign.left,
  211. );
  212. }
  213. Widget buildConnectingText() {
  214. return const Row(
  215. children: [
  216. Expanded(
  217. child: Text(
  218. '设备连接中',
  219. style: TextStyle(
  220. fontSize: 40,
  221. color: Colors.blue,
  222. ),
  223. ),
  224. ),
  225. CircularProgressIndicator(
  226. valueColor: AlwaysStoppedAnimation(
  227. Colors.blue,
  228. ),
  229. ),
  230. SizedBox(
  231. width: 20,
  232. ),
  233. ],
  234. );
  235. }
  236. Widget buildReconnectButton() {
  237. return Container(
  238. margin: const EdgeInsets.only(top: 4),
  239. width: 134,
  240. child: VButton(
  241. onTap: () async {
  242. /// TODO
  243. await connect();
  244. worker.connectErrorEvent.addListener(_onConnectFail);
  245. worker.connectedEvent.addListener(_onConnectSuccess);
  246. /// TODO 后面需要改,这边暂时演示用
  247. Future.delayed(const Duration(milliseconds: 8000), () {
  248. if (!connectSuccessState) {
  249. connectFailState = true;
  250. }
  251. });
  252. },
  253. child: const Row(
  254. mainAxisAlignment: MainAxisAlignment.center,
  255. children: [
  256. Icon(Icons.connected_tv_rounded, size: 24),
  257. SizedBox(
  258. width: 8,
  259. ),
  260. Text("重连", style: TextStyle(fontSize: 20)),
  261. ],
  262. ),
  263. ),
  264. );
  265. }
  266. Widget buildConnectStateWidgets() {
  267. return Column(
  268. children: [
  269. if (connectFailState) buildConnectFailText(),
  270. if (connectSuccessState) buildConnectSuccessText(),
  271. if (isConnect)
  272. buildConnectingText()
  273. else if (connectFailState)
  274. buildReconnectButton(),
  275. ],
  276. );
  277. }
  278. Widget buildMainWidget() {
  279. return SizedBox(
  280. height: 100,
  281. child: Row(
  282. children: [
  283. buildInputField(),
  284. Expanded(
  285. child: buildConnectStateWidgets(),
  286. ),
  287. ],
  288. ),
  289. );
  290. }
  291. }