|
@@ -61,146 +61,158 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
Widget build(BuildContext context) {
|
|
|
return Stack(
|
|
|
children: [
|
|
|
- ExamCard(
|
|
|
- titleText: const SizedBox(),
|
|
|
- content: SizedBox(
|
|
|
- height: 620,
|
|
|
- // margin: const EdgeInsets.only(bottom: 10),
|
|
|
- child: Column(
|
|
|
- children: [
|
|
|
- Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.end,
|
|
|
- children: [
|
|
|
- const Expanded(child: SizedBox()),
|
|
|
- const Text(
|
|
|
- "心率",
|
|
|
- style: TextStyle(
|
|
|
- fontSize: 24,
|
|
|
- color: Colors.black,
|
|
|
- ),
|
|
|
- ),
|
|
|
- const SizedBox(
|
|
|
- width: 10,
|
|
|
- ),
|
|
|
- Text(
|
|
|
- _heart.isEmpty ? '--' : _heart,
|
|
|
- style: const TextStyle(
|
|
|
- fontSize: 60,
|
|
|
- color: Colors.black,
|
|
|
- ),
|
|
|
- ),
|
|
|
- const Text(
|
|
|
- " bpm",
|
|
|
- style: TextStyle(fontSize: 25),
|
|
|
- ),
|
|
|
- const SizedBox(
|
|
|
- width: 250,
|
|
|
- )
|
|
|
- ],
|
|
|
- ),
|
|
|
- Expanded(
|
|
|
- child: ListView(
|
|
|
- shrinkWrap: true,
|
|
|
- children: [
|
|
|
- SizedBox(
|
|
|
- height: 520,
|
|
|
- child: LayoutBuilder(builder: (context, constraints) {
|
|
|
- if (initEcgData == null) {
|
|
|
- return Container();
|
|
|
- } else {
|
|
|
- return TwelveEcgView(
|
|
|
- width: constraints.maxWidth,
|
|
|
- height: constraints.maxHeight,
|
|
|
- initData: initEcgData!,
|
|
|
- currentIndex: 0,
|
|
|
- isConclusion: _assess.isNotEmpty,
|
|
|
- );
|
|
|
- }
|
|
|
- }),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
+ _buildEcgView(),
|
|
|
+ DeviceStatusPosition(
|
|
|
+ currentTop: 24,
|
|
|
+ deviceStatus: EcgDeviceStatus(
|
|
|
+ connectStatus: connectStatus,
|
|
|
),
|
|
|
),
|
|
|
- if (!isConnectFail)
|
|
|
- DeviceStatusPosition(
|
|
|
- currentTop: 24,
|
|
|
- deviceStatus: EcgDeviceStatus(
|
|
|
- connectStatus: connectStatus,
|
|
|
- connectEcg: tryReconnect,
|
|
|
- ),
|
|
|
- )
|
|
|
- else
|
|
|
- _buildErrorButton(),
|
|
|
if (twelveEcgStatus == TwelveEcgStatus.unstableSampling)
|
|
|
- const Positioned(
|
|
|
- left: 20,
|
|
|
- top: 24,
|
|
|
- child: Text(
|
|
|
- '波形正在稳定中',
|
|
|
- style: TextStyle(fontSize: 24, color: Colors.blue),
|
|
|
- ),
|
|
|
- ),
|
|
|
+ _buildUnstableSampling(),
|
|
|
if (twelveEcgStatus == TwelveEcgStatus.stableSampling)
|
|
|
- Positioned(
|
|
|
- left: 20,
|
|
|
- top: 24,
|
|
|
- child: Row(
|
|
|
- children: const [
|
|
|
- CountdownPage(
|
|
|
- seconds: 30,
|
|
|
+ _buildCountdownPage(),
|
|
|
+ _buildOperateButton(),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildEcgView() {
|
|
|
+ return ExamCard(
|
|
|
+ titleText: const SizedBox(),
|
|
|
+ content: SizedBox(
|
|
|
+ height: 620,
|
|
|
+ // margin: const EdgeInsets.only(bottom: 10),
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
+ Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.end,
|
|
|
+ children: [
|
|
|
+ const Expanded(child: SizedBox()),
|
|
|
+ const Text(
|
|
|
+ "心率",
|
|
|
+ style: TextStyle(
|
|
|
+ fontSize: 24,
|
|
|
+ color: Colors.black,
|
|
|
+ ),
|
|
|
),
|
|
|
+ const SizedBox(
|
|
|
+ width: 10,
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ _heart.isEmpty ? '--' : _heart,
|
|
|
+ style: const TextStyle(
|
|
|
+ fontSize: 60,
|
|
|
+ color: Colors.black,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ const Text(
|
|
|
+ " bpm",
|
|
|
+ style: TextStyle(fontSize: 25),
|
|
|
+ ),
|
|
|
+ const SizedBox(
|
|
|
+ width: 250,
|
|
|
+ )
|
|
|
],
|
|
|
),
|
|
|
+ Expanded(
|
|
|
+ child: ListView(
|
|
|
+ shrinkWrap: true,
|
|
|
+ children: [
|
|
|
+ SizedBox(
|
|
|
+ height: 520,
|
|
|
+ child: LayoutBuilder(builder: (context, constraints) {
|
|
|
+ if (initEcgData == null) {
|
|
|
+ return Container();
|
|
|
+ } else {
|
|
|
+ return TwelveEcgView(
|
|
|
+ width: constraints.maxWidth,
|
|
|
+ height: constraints.maxHeight,
|
|
|
+ initData: initEcgData!,
|
|
|
+ currentIndex: 0,
|
|
|
+ isConclusion: _assess.isNotEmpty,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildUnstableSampling() {
|
|
|
+ return const Positioned(
|
|
|
+ left: 20,
|
|
|
+ top: 24,
|
|
|
+ child: Text(
|
|
|
+ '波形正在稳定中',
|
|
|
+ style: TextStyle(fontSize: 24, color: Colors.blue),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildCountdownPage() {
|
|
|
+ return Positioned(
|
|
|
+ left: 20,
|
|
|
+ top: 24,
|
|
|
+ child: Row(
|
|
|
+ children: const [
|
|
|
+ CountdownPage(
|
|
|
+ seconds: 30,
|
|
|
),
|
|
|
- Positioned(
|
|
|
- left: 24,
|
|
|
- top: 24,
|
|
|
- child: Row(
|
|
|
- children: [
|
|
|
- if (twelveEcgStatus == TwelveEcgStatus.noSampling &&
|
|
|
- (connectStatus == WorkerStatus.connectionFailed ||
|
|
|
- connectStatus == WorkerStatus.disconnected)) ...[
|
|
|
- SizedBox(
|
|
|
- width: 150,
|
|
|
- height: 50,
|
|
|
- child: VButton(
|
|
|
- onTap: () => connectStatus == WorkerStatus.connecting
|
|
|
- ? null
|
|
|
- : connect(),
|
|
|
- child: const Center(
|
|
|
- child: Text(
|
|
|
- "采样",
|
|
|
- style: TextStyle(fontSize: 24),
|
|
|
- ),
|
|
|
- ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildOperateButton() {
|
|
|
+ return Positioned(
|
|
|
+ left: 24,
|
|
|
+ top: 24,
|
|
|
+ child: Row(
|
|
|
+ children: [
|
|
|
+ if (twelveEcgStatus == TwelveEcgStatus.noSampling &&
|
|
|
+ (connectStatus == WorkerStatus.connectionFailed ||
|
|
|
+ connectStatus == WorkerStatus.disconnected ||
|
|
|
+ connectStatus == WorkerStatus.boundDeviceFail)) ...[
|
|
|
+ SizedBox(
|
|
|
+ width: 150,
|
|
|
+ height: 50,
|
|
|
+ child: VButton(
|
|
|
+ onTap: () =>
|
|
|
+ connectStatus == WorkerStatus.connecting ? null : connect(),
|
|
|
+ child: const Center(
|
|
|
+ child: Text(
|
|
|
+ "采样",
|
|
|
+ style: TextStyle(fontSize: 24),
|
|
|
),
|
|
|
),
|
|
|
- const SizedBox(
|
|
|
- width: 20,
|
|
|
- ),
|
|
|
- ],
|
|
|
- if (_assess.isNotEmpty)
|
|
|
- SizedBox(
|
|
|
- width: 150,
|
|
|
- height: 50,
|
|
|
- child: VButton(
|
|
|
- onTap: () => _openConclusion(),
|
|
|
- child: const Center(
|
|
|
- child: Text(
|
|
|
- "查看结果",
|
|
|
- style: TextStyle(fontSize: 24),
|
|
|
- ),
|
|
|
- ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ const SizedBox(
|
|
|
+ width: 20,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ if (_assess.isNotEmpty)
|
|
|
+ SizedBox(
|
|
|
+ width: 150,
|
|
|
+ height: 50,
|
|
|
+ child: VButton(
|
|
|
+ onTap: () => _openConclusion(),
|
|
|
+ child: const Center(
|
|
|
+ child: Text(
|
|
|
+ "查看结果",
|
|
|
+ style: TextStyle(fontSize: 24),
|
|
|
),
|
|
|
),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -236,9 +248,9 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
}
|
|
|
|
|
|
Future<void> connect() async {
|
|
|
- await worker.connect();
|
|
|
connectStatus = WorkerStatus.connecting;
|
|
|
isConnectFail = false;
|
|
|
+ await worker.connect();
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
@@ -302,6 +314,9 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
}
|
|
|
|
|
|
void loadListeners() {
|
|
|
+ worker.boundingEvent.addListener(_onBounding);
|
|
|
+ worker.boundSuccessEvent.addListener(_onBoundSuccess);
|
|
|
+ worker.boundFailEvent.addListener(_onBoundFail);
|
|
|
worker.connectErrorEvent.addListener(_onConnectFail);
|
|
|
worker.connectedEvent.addListener(_onConnectSuccess);
|
|
|
worker.disconnectedEvent.addListener(_onDisconnected);
|
|
@@ -312,6 +327,9 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
}
|
|
|
|
|
|
void releaseListeners() {
|
|
|
+ worker.boundingEvent.removeListener(_onBounding);
|
|
|
+ worker.boundSuccessEvent.removeListener(_onBoundSuccess);
|
|
|
+ worker.boundFailEvent.removeListener(_onBoundFail);
|
|
|
worker.connectErrorEvent.removeListener(_onConnectFail);
|
|
|
worker.connectedEvent.removeListener(_onConnectSuccess);
|
|
|
worker.disconnectedEvent.removeListener(_onDisconnected);
|
|
@@ -370,7 +388,7 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
|
- void _onSaveSuccess(semder, e) async {
|
|
|
+ void _onSaveSuccess(sender, e) async {
|
|
|
if (e) {
|
|
|
PromptBox.toast("采样结束");
|
|
|
twelveEcgStatus = TwelveEcgStatus.noSampling;
|
|
@@ -378,6 +396,21 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
|
+ void _onBounding(sender, e) {
|
|
|
+ connectStatus = WorkerStatus.boundingDevice;
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+
|
|
|
+ void _onBoundSuccess(sender, e) {
|
|
|
+ tryReconnect();
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+
|
|
|
+ void _onBoundFail(sender, e) {
|
|
|
+ connectStatus = WorkerStatus.boundDeviceFail;
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+
|
|
|
void _onConnectSuccess(sender, e) {
|
|
|
logger.i('_HeartRateState ${worker.mac}, 设备连接成功');
|
|
|
twelveEcgStatus = TwelveEcgStatus.unstableSampling;
|
|
@@ -386,7 +419,6 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
connectStatus = WorkerStatus.connected;
|
|
|
resetEcgView();
|
|
|
_assess = "";
|
|
|
-
|
|
|
setState(() {});
|
|
|
}
|
|
|
|