body_weight.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  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/managers/interfaces/permission.dart';
  5. import 'package:vnoteapp/pages/check/models/form.dart';
  6. import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_card.dart';
  7. import 'package:vnoteapp/components/dialog_number.dart';
  8. import 'package:vnoteapp/pages/check/widgets/exam_device_connect_status/connect.dart';
  9. import 'package:vnoteapp/pages/check/widgets/exam_device_connect_status/connect_disconnected.dart';
  10. import 'package:vnoteapp/pages/check/widgets/exam_device_connect_status/connect_fail.dart';
  11. import 'package:vnoteapp/pages/check/widgets/exam_device_connect_status/connect_success.dart';
  12. // ignore: must_be_immutable
  13. class BodyWeight extends StatefulWidget {
  14. const BodyWeight({
  15. super.key,
  16. });
  17. @override
  18. State<BodyWeight> createState() => _ExamBodyWeightState();
  19. }
  20. class _ExamBodyWeightState extends State<BodyWeight> {
  21. var permissionManager = Get.find<IPermissionManager>();
  22. late final WeightDeviceWorker worker = WeightDeviceWorker(
  23. mac: 'CF:E4:2C:22:01:39',
  24. model: 'CF398BLE',
  25. );
  26. /// 设备连接失败的状态
  27. bool _connectFailStatus = false;
  28. /// 设备连接中断的状态
  29. bool _connectDisconnectedStatus = false;
  30. /// 设备连接成功的状态
  31. bool _connectSuccessStatus = false;
  32. /// 设备是否连接中
  33. bool _isConnect = false;
  34. String _value = '';
  35. @override
  36. void initState() {
  37. getPermission();
  38. worker.successEvent.addListener(_onSuccess);
  39. worker.connectErrorEvent.addListener(_onConnectFail);
  40. worker.connectedEvent.addListener(_onConnectSuccess);
  41. worker.disconnectedEvent.addListener(_onDisconnected);
  42. connect();
  43. super.initState();
  44. }
  45. Future<void> connect() async {
  46. _connectFailStatus = false;
  47. _isConnect = true;
  48. _connectSuccessStatus = false;
  49. _connectDisconnectedStatus = false;
  50. setState(() {});
  51. await worker.connect();
  52. }
  53. Future<void> disconnect() async {
  54. worker.connectErrorEvent.removeListener(_onConnectFail);
  55. worker.connectedEvent.removeListener(_onConnectSuccess);
  56. worker.successEvent.removeListener(_onSuccess);
  57. worker.disconnectedEvent.removeListener(_onDisconnected);
  58. await worker.disconnect();
  59. }
  60. @override
  61. void dispose() {
  62. disconnect();
  63. super.dispose();
  64. }
  65. void _onSuccess(_, double e) {
  66. setState(() {
  67. _value = e.toString();
  68. _isConnect = false;
  69. });
  70. }
  71. void _onConnectFail(sender, e) {
  72. print('连接设备失败');
  73. _connectFailStatus = true;
  74. _connectSuccessStatus = false;
  75. _connectDisconnectedStatus = false;
  76. _isConnect = false;
  77. setState(() {});
  78. }
  79. void _onConnectSuccess(sender, e) {
  80. _connectSuccessStatus = true;
  81. _isConnect = false;
  82. _connectFailStatus = false;
  83. _connectDisconnectedStatus = false;
  84. setState(() {});
  85. }
  86. void _onDisconnected(sender, e) {
  87. print('设备连接中断');
  88. _connectDisconnectedStatus = true;
  89. _connectSuccessStatus = false;
  90. _connectFailStatus = false;
  91. _isConnect = false;
  92. setState(() {});
  93. }
  94. Future<void> getPermission() async {
  95. await permissionManager.requestLocationPermission();
  96. await permissionManager.requestBluetoothConnectPermission();
  97. await permissionManager.requestBluetoothAdvertisePermission();
  98. await permissionManager.requestBluetoothScanPermission();
  99. }
  100. @override
  101. Widget build(BuildContext context) {
  102. return Stack(
  103. children: [
  104. _buildTemperature(),
  105. if (_connectFailStatus)
  106. DeviceConnectFail(
  107. connect: () => connect(),
  108. ),
  109. if (_connectSuccessStatus) const DeviceConnectSuccess(),
  110. if (_isConnect) const DeviceConnect(),
  111. if (_connectDisconnectedStatus)
  112. DeviceConnectDisconnected(
  113. connect: () => connect(),
  114. ),
  115. ],
  116. );
  117. }
  118. Widget _buildTemperature() {
  119. return ExamCard(
  120. title: '体重',
  121. clickCard: () {
  122. _inputTemperature();
  123. },
  124. content: Container(
  125. alignment: Alignment.bottomRight,
  126. padding: const EdgeInsets.only(
  127. bottom: 20,
  128. right: 30,
  129. left: 40,
  130. ),
  131. constraints: const BoxConstraints(minHeight: 150),
  132. child: FittedBox(
  133. child: Row(
  134. mainAxisAlignment: MainAxisAlignment.end,
  135. crossAxisAlignment: CrossAxisAlignment.end,
  136. children: [
  137. RichText(
  138. text: TextSpan(
  139. text: _value,
  140. style: const TextStyle(
  141. fontSize: 80,
  142. color: Colors.black,
  143. ),
  144. children: const [
  145. TextSpan(
  146. text: 'kg',
  147. style: TextStyle(fontSize: 25),
  148. )
  149. ],
  150. ),
  151. ),
  152. ],
  153. ),
  154. ),
  155. ),
  156. );
  157. }
  158. Future<void> _inputTemperature() async {
  159. String? result = await VDialogNumber(
  160. title: '体重',
  161. initialValue: _value,
  162. ).show();
  163. if (result?.isNotEmpty ?? false) {
  164. _value = result ?? '';
  165. }
  166. }
  167. }
  168. // class BodyWeight extends StatefulWidget {
  169. // const BodyWeight({
  170. // super.key,
  171. // required this.currentFormObject,
  172. // required this.currentInputValue,
  173. // this.specialInput,
  174. // });
  175. // final FormObject currentFormObject;
  176. // final String currentInputValue;
  177. // final Function(String value)? specialInput;
  178. // @override
  179. // State<ExamBodyWeight> createState() => _ExamBodyWeightState();
  180. // }
  181. // class _ExamBodyWeightState extends State<ExamBodyWeight> {
  182. // var permissionManager = Get.find<IPermissionManager>();
  183. // @override
  184. // void initState() {
  185. // getPermission();
  186. // super.initState();
  187. // }
  188. // Future<void> getPermission() async {
  189. // await permissionManager.requestLocationPermission();
  190. // await permissionManager.requestBluetoothConnectPermission();
  191. // await permissionManager.requestBluetoothAdvertisePermission();
  192. // await permissionManager.requestBluetoothScanPermission();
  193. // }
  194. // @override
  195. // Widget build(BuildContext context) {
  196. // return ExamCard(
  197. // title: widget.currentFormObject.label ?? '',
  198. // clickCard: () {
  199. // _buildTempertureInput(widget.currentFormObject);
  200. // },
  201. // content: Container(
  202. // alignment: Alignment.bottomRight,
  203. // padding: const EdgeInsets.only(
  204. // bottom: 20,
  205. // right: 30,
  206. // left: 40,
  207. // ),
  208. // constraints: const BoxConstraints(minHeight: 150),
  209. // child: FittedBox(
  210. // child: Row(
  211. // mainAxisAlignment: MainAxisAlignment.end,
  212. // crossAxisAlignment: CrossAxisAlignment.end,
  213. // children: [
  214. // RichText(
  215. // text: TextSpan(
  216. // text: widget.currentInputValue,
  217. // style: const TextStyle(
  218. // fontSize: 80,
  219. // color: Colors.black,
  220. // ),
  221. // children: [
  222. // TextSpan(
  223. // text: widget.currentFormObject.append ?? '',
  224. // style: const TextStyle(fontSize: 25),
  225. // )
  226. // ],
  227. // ),
  228. // ),
  229. // ],
  230. // ),
  231. // ),
  232. // ),
  233. // );
  234. // }
  235. // Future<void> _buildTempertureInput(FormObject currentFormObject) async {
  236. // // Future.delayed(const Duration(milliseconds: 3000), () {
  237. // // specialInputController.text = generateRandomNumber().toString();
  238. // // widget.specialInput?.call(specialInputController.text);
  239. // // setState(() {});
  240. // // });
  241. // final result = await Get.dialog(
  242. // Weight(
  243. // currentFormObject: widget.currentFormObject,
  244. // weight: widget.currentInputValue,
  245. // ),
  246. // barrierDismissible: false,
  247. // );
  248. // widget.specialInput?.call(result);
  249. // print('object');
  250. // print(result);
  251. // print('object');
  252. // }
  253. // }
  254. // class Weight extends StatefulWidget {
  255. // const Weight({
  256. // super.key,
  257. // required this.currentFormObject,
  258. // this.weight,
  259. // });
  260. // final FormObject currentFormObject;
  261. // final String? weight;
  262. // @override
  263. // State<Weight> createState() => _WeightState();
  264. // }
  265. // class _WeightState extends State<Weight> {
  266. // late final WeightDeviceWorker worker = WeightDeviceWorker(
  267. // mac: 'CF:E4:2C:22:01:39',
  268. // model: 'CF398BLE',
  269. // );
  270. // late TextEditingController specialInputController =
  271. // TextEditingController(text: widget.weight ?? '00.0');
  272. // bool connectFailState = false;
  273. // bool connectSuccessState = false;
  274. // bool isConnect = false;
  275. // @override
  276. // void initState() {
  277. // connect();
  278. // worker.successEvent.addListener(_onSuccess);
  279. // worker.connectErrorEvent.addListener(_onConnectFail);
  280. // worker.connectedEvent.addListener(_onConnectSuccess);
  281. // super.initState();
  282. // }
  283. // Future<void> connect() async {
  284. // connectFailState = false;
  285. // isConnect = true;
  286. // connectSuccessState = false;
  287. // setState(() {});
  288. // await worker.connect();
  289. // }
  290. // Future<void> disconnect() async {
  291. // worker.connectErrorEvent.removeListener(_onConnectFail);
  292. // worker.connectedEvent.removeListener(_onConnectSuccess);
  293. // worker.successEvent.removeListener(_onSuccess);
  294. // await worker.disconnect();
  295. // }
  296. // @override
  297. // void dispose() {
  298. // super.dispose();
  299. // }
  300. // void _onSuccess(_, double e) {
  301. // setState(() {
  302. // specialInputController.text = e.toString();
  303. // // connectFailState = false;
  304. // // connectSuccessState = false;
  305. // isConnect = false;
  306. // // disconnect();
  307. // });
  308. // }
  309. // void _onConnectFail(sender, e) {
  310. // print('连接设备失败');
  311. // connectFailState = true;
  312. // connectSuccessState = false;
  313. // isConnect = false;
  314. // disconnect();
  315. // setState(() {});
  316. // }
  317. // void _onConnectSuccess(sender, e) {
  318. // connectSuccessState = true;
  319. // connectFailState = false;
  320. // isConnect = false;
  321. // setState(() {});
  322. // }
  323. // @override
  324. // Widget build(BuildContext context) {
  325. // return VAlertDialog(
  326. // title: widget.currentFormObject.label ?? '',
  327. // width: 600,
  328. // contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
  329. // content: buildMainWidget(),
  330. // showCancel: true,
  331. // onConfirm: () {
  332. // disconnect();
  333. // Get.back(result: specialInputController.text);
  334. // },
  335. // onCanceled: () {
  336. // disconnect();
  337. // },
  338. // );
  339. // }
  340. // Widget buildInputField() {
  341. // return Container(
  342. // width: 350,
  343. // padding: const EdgeInsets.only(left: 15),
  344. // child: TextFormField(
  345. // keyboardType: TextInputType.number,
  346. // style: const TextStyle(
  347. // fontSize: 100,
  348. // ),
  349. // showCursor: false,
  350. // controller: specialInputController,
  351. // decoration: const InputDecoration(
  352. // labelStyle: TextStyle(
  353. // fontSize: 100,
  354. // ),
  355. // ),
  356. // ),
  357. // );
  358. // }
  359. // Widget buildConnectFailText() {
  360. // return const Text(
  361. // '设备连接失败',
  362. // style: TextStyle(
  363. // color: Colors.red,
  364. // fontSize: 25,
  365. // ),
  366. // textAlign: TextAlign.left,
  367. // );
  368. // }
  369. // Widget buildConnectSuccessText() {
  370. // return const Text(
  371. // '设备连接成功',
  372. // style: TextStyle(
  373. // color: Colors.green,
  374. // fontSize: 25,
  375. // ),
  376. // textAlign: TextAlign.left,
  377. // );
  378. // }
  379. // Widget buildConnectingText() {
  380. // return const Row(
  381. // children: [
  382. // Expanded(
  383. // child: Text(
  384. // '设备连接中',
  385. // style: TextStyle(
  386. // fontSize: 40,
  387. // color: Colors.blue,
  388. // ),
  389. // ),
  390. // ),
  391. // CircularProgressIndicator(
  392. // valueColor: AlwaysStoppedAnimation(
  393. // Colors.blue,
  394. // ),
  395. // ),
  396. // SizedBox(
  397. // width: 20,
  398. // ),
  399. // ],
  400. // );
  401. // }
  402. // Widget buildReconnectButton() {
  403. // return Container(
  404. // margin: const EdgeInsets.only(top: 4),
  405. // width: 134,
  406. // child: VButton(
  407. // onTap: () async {
  408. // /// TODO
  409. // await connect();
  410. // worker.connectErrorEvent.addListener(_onConnectFail);
  411. // worker.connectedEvent.addListener(_onConnectSuccess);
  412. // /// TODO 后面需要改,这边暂时演示用
  413. // Future.delayed(const Duration(milliseconds: 8000), () {
  414. // if (!connectSuccessState) {
  415. // connectFailState = true;
  416. // }
  417. // });
  418. // },
  419. // child: const Row(
  420. // mainAxisAlignment: MainAxisAlignment.center,
  421. // children: [
  422. // Icon(Icons.connected_tv_rounded, size: 24),
  423. // SizedBox(
  424. // width: 8,
  425. // ),
  426. // Text("重连", style: TextStyle(fontSize: 20)),
  427. // ],
  428. // ),
  429. // ),
  430. // );
  431. // }
  432. // Widget buildConnectStateWidgets() {
  433. // return Column(
  434. // children: [
  435. // if (connectFailState) buildConnectFailText(),
  436. // if (connectSuccessState) buildConnectSuccessText(),
  437. // if (isConnect)
  438. // buildConnectingText()
  439. // else if (connectFailState)
  440. // buildReconnectButton(),
  441. // ],
  442. // );
  443. // }
  444. // Widget buildMainWidget() {
  445. // return SizedBox(
  446. // height: 100,
  447. // child: Row(
  448. // children: [
  449. // buildInputField(),
  450. // Expanded(
  451. // child: buildConnectStateWidgets(),
  452. // ),
  453. // ],
  454. // ),
  455. // );
  456. // }
  457. // }