exam_body_weight.dart 8.2 KB

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