1.搭建心率检测Slice;2.开启通话记录Slice;3.更正主界面心率界面检测效果;4.后续填补model
authorCaisking <3449750381@qq.com>
Tue, 5 Mar 2024 03:58:05 +0000 (11:58 +0800)
committerCaisking <3449750381@qq.com>
Tue, 5 Mar 2024 03:58:05 +0000 (11:58 +0800)
21 files changed:
code/sdk/application/wearable/fd230app/CMakeLists.txt
code/sdk/application/wearable/fd230app/nativelauncher/include/NativeLauncher.h
code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h
code/sdk/application/wearable/fd230app/nativelauncher/src/NativeLauncher.cpp
code/sdk/application/wearable/fd230app/nativeui/applist/src/ApplistModel.cpp
code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartResultView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartRateView.cpp
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartResultView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp [new file with mode: 0644]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/APPLIST_CALLLOG.bin [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/service/ppg_service.cpp

index 7c64f8a..e5254e0 100644 (file)
@@ -199,6 +199,10 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/activity/src/ActivityModel.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartRateView.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartModel.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartCheckView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartResultView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heartrate/src/HeartPresenter.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/alarm/src/AlarmClockModel.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/alarm/src/MainAlarmView.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/alarm/src/AlarmConfigView.cpp
index 067ac99..207125a 100644 (file)
@@ -55,6 +55,7 @@ namespace OHOS
         /* --------------------------------测试界面------------------------------------ */
         void InitRotateSlice(void);
         void InitBloodSlice(void);
+        void InitHeartSlice(void);
         void InitMainAlipaySlice(void);
         void InitDialUpdateSlice(void);
         /* -------------------------------------------------------------------------- */
index 692839c..1f48666 100644 (file)
@@ -223,7 +223,6 @@ namespace OHOS
     static constexpr const char *PNG_ALIPAY_LIST_HELP = APP_RES_PATH "/alipay/ALIPAY_LIST_HELP.bin";
     static constexpr const char *PNG_ALIPAY_PAY_ICON_WHITE = APP_RES_PATH "/alipay/ALIPAY_PAY_ICON_WHITE.bin";
     static constexpr const char *PNG_ALIPAY_PAY_ICON_GREY = APP_RES_PATH "/alipay/ALIPAY_PAY_ICON_GREY.bin";
-    /* -------------------------------------------------------------------------- */
     /* ----------------------------------- 录音 ----------------------------------- */
     static constexpr const char *PNG_ANIMATOR1_IMAGE = APP_RES_PATH "/record/animator1.bin";
     static constexpr const char *PNG_ANIMATOR2_IMAGE = APP_RES_PATH "/record/animator2.bin";
@@ -289,6 +288,7 @@ namespace OHOS
     static constexpr const char *PNG_APPLIST_HEART_IMAGE = APP_RES_PATH "/APPLIST_HEART.bin";           // 心率
     static constexpr const char *PNG_APPLIST_SETTING_IMAGE = APP_RES_PATH "/APPLIST_SETTING.bin";       // 设置
     static constexpr const char *PNG_APPLIST_CALLER_IMAGE = APP_RES_PATH "/APPLIST_CALLER_IMAGE.bin";   // 打电话
+    static constexpr const char *PNG_APPLIST_CALLLOG_IMAGE = APP_RES_PATH "/APPLIST_CALLLOG.bin";       // 1通话记录
     static constexpr const char *PNG_APPLIST_COMPASS_IMAGE = APP_RES_PATH "/APPLIST_COMPASS_IMAGE.bin"; // 指南针
     static constexpr const char *PNG_APPLIST_WEATHER_IMAGE = APP_RES_PATH "/APPLIST_WEATHER_IMAGE.bin"; // 天气
     static constexpr const char *PNG_APPLIST_RECORD_IMAGE = APP_RES_PATH "/APPLIST_RECORD_IMAGE.bin";   // 录音
index 54a07f6..2778ea2 100644 (file)
@@ -25,6 +25,9 @@
 #include "ApplistPresenter.h"
 #include "BloodOxygenView.h"
 #include "BloodOxygenPresenter.h"
+#include "heartrate/include/HeartPresenter.h"
+#include "heartrate/include/HeartView.h"
+#include "HeartPresenter.h"
 #include "CallerLogView.h"
 #include "CallerLogPresenter.h"
 #include "MainCallingView.h"
@@ -85,7 +88,6 @@
 #include "message/include/MessageModel.h"
 #include "message/include/MessagePresenter.h"
 
-
 #include "secondaryfunction/include/SecondaryFunctionPresenter.h"
 #include "secondaryfunction/include/SecondaryFunctionView.h"
 #include "secondaryfunction/include/FastTrainingPresenter.h"
@@ -147,7 +149,6 @@ namespace OHOS
         {VIEW_BLUETOOTH_EARPHONE, &NativeLauncher::InitBluetoothSlice},
         {VIEW_CALLER_LOG, &NativeLauncher::InitMainCallerLogView},
         {VIEW_INCOMING_CALL, &NativeLauncher::InitMainMakePhoneView},
-        {VIEW_BLOODOXY, &NativeLauncher::InitMainBloodOxyView},
         {VIEW_COMPASS, &NativeLauncher::InitCompassSlice},
         {VIEW_CONNECT_PHONE, &NativeLauncher::InitConnectPhoneSlice},
         {VIEW_INDOORWALK, &NativeLauncher::InitIndoorWalkSlice},
@@ -174,6 +175,8 @@ namespace OHOS
         {VIEW_MESSAGE, &NativeLauncher::InitMessageSlice},
         {VIEW_ROTATE, &NativeLauncher::InitRotateSlice},
         {VIEW_DIALUPDATE, &NativeLauncher::InitDialUpdateSlice},
+        {VIEW_BLOODOXY, &NativeLauncher::InitMainBloodOxyView},
+        {VIEW_HEART, &NativeLauncher::InitHeartSlice},
 #ifdef SUPPORT_ALIPAY_SEC
         {VIEW_MAIN_ALIPAY, &NativeLauncher::InitMainAlipaySlice},
 #endif
@@ -364,6 +367,17 @@ namespace OHOS
         }
         NativeAbility::GetInstance().AddSliceProxy(VIEW_ALARM_POP_UP, alarmPopUpView);
     }
+    void NativeLauncher::InitHeartSlice(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NativeLauncher::HeartSlice");
+        SliceProxy *heartView = new AbilitySliceProxy<HeartView, HeartPresenter>;
+        if (heartView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartView is nullptr");
+            return;
+        }
+        NativeAbility::GetInstance().AddSliceProxy(VIEW_HEART, heartView);
+    }
 
     void NativeLauncher::InitMainBloodOxyView(void)
     {
@@ -612,10 +626,10 @@ namespace OHOS
         }
         NativeAbility::GetInstance().AddSliceProxy(VIEW_ROTATE, rotate);
     }
-    void NativeLauncher::InitDialUpdateSlice(void)    //切换表盘
+    void NativeLauncher::InitDialUpdateSlice(void) // 切换表盘
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "NativeLauncher::InitDialUpdateSlice");
-        SliceProxy *dialupdate= new AbilitySliceProxy<DialUpdateView, DialUpdatePresenter>;
+        SliceProxy *dialupdate = new AbilitySliceProxy<DialUpdateView, DialUpdatePresenter>;
         if (dialupdate == nullptr)
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "dialupdate");
index 45b6590..2d05348 100644 (file)
@@ -25,16 +25,16 @@ namespace OHOS
         {VIEW_COMPASS, PNG_APPLIST_COMPASS_IMAGE, PNG_APPLIST_COMPASS_IMAGE, "指南针", nullptr},
         {VIEW_INDOORWALK, PNG_APPLIST_WALK_IMAGE, PNG_APPLIST_WALK_IMAGE, "室内步行", nullptr},
         {VIEW_WEATHER, PNG_APPLIST_WEATHER_IMAGE, PNG_APPLIST_WEATHER_IMAGE, "天气", nullptr},
+        {VIEW_HEART, PNG_APPLIST_HEART_IMAGE, PNG_APPLIST_HEART_IMAGE, "心率检测", nullptr},
         {VIEW_RECORD, PNG_APPLIST_RECORD_IMAGE, PNG_APPLIST_RECORD_IMAGE, "录音", nullptr},
         {VIEW_SETTING, PNG_APPLIST_SETTING_IMAGE, PNG_APPLIST_SETTING_IMAGE, "设置", nullptr},
         {VIEW_DIALUPDATE, PNG_APPLIST_UI_SAMPLE_IMAGE, PNG_APPLIST_UI_SAMPLE_IMAGE, "表盘切换", nullptr},
+        {VIEW_CALLER_LOG, PNG_APPLIST_CALLLOG_IMAGE, PNG_APPLIST_CALLLOG_IMAGE, "通话记录", nullptr},
 #ifdef SUPPORT_ALIPAY_SEC
         {VIEW_MAIN_ALIPAY, PNG_APPLIST_ALIPAY_IMAGE, PNG_APPLIST_ALIPAY_IMAGE, "支付宝", nullptr},
 #endif
 #if 0
-        {VIEW_HEART, PNG_APPLIST_HEART_IMAGE, PNG_APPLIST_HEART_IMAGE, "心率检测", nullptr},
         {VIEW_MAIN_TEMP, PNG_APPLIST_TEMP_IMAGE, PNG_APPLIST_TEMP_IMAGE, "体温", nullptr},
-        {VIEW_CALLER_LOG, PNG_APPLIST_CALLER_IMAGE, PNG_APPLIST_CALLER_IMAGE, "通话记录", nullptr},
         {VIEW_OFFLINEVOICE, PNG_APPLIST_VOCASSIST_IMAGE, PNG_APPLIST_VOCASSIST_IMAGE, "语音助手", nullptr},
         {VIEW_UISAMPLE, PNG_APPLIST_UI_SAMPLE_IMAGE, PNG_APPLIST_UI_SAMPLE_IMAGE, "示例", nullptr},
         {VIEW_MESSAGE, PNG_APPLIST_CALLER_IMAGE, PNG_APPLIST_CALLER_IMAGE, "信息通知", nullptr},
index 4aa92f6..b635c66 100644 (file)
@@ -262,7 +262,7 @@ namespace OHOS
             if (BloodCheckView::GetInstance()->GetImageAnimator()->GetState() == false)
             {
                 // 测试失败
-                if (BloodOxygenModel::GetInstance()->GetSPO2data() == 0)
+                if (BloodOxygenModel::GetInstance()->GetShowSPO2data() == 0)
                 {
                     BloodOxygenView::GetInstance()->ChangeView(BLOODCHECKVIEW, BLOODRESULT);
                 }
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartBandoffView.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartCheckView.h
new file mode 100644 (file)
index 0000000..26c62b0
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodCheck view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef HEART_Check_VIEW_H
+#define HEART_Check_VIEW_H
+
+#include "View.h"
+#include "BaseView.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "components/ui_label.h"
+#include "components/ui_button.h"
+#include "components/ui_label_button.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_view_group.h"
+#include "HeartPresenter.h"
+#include "components/ui_scroll_view.h"
+namespace OHOS
+{
+    class HeartPresenter;
+    class HeartBandoffView;
+
+    class HeartCheckView : public View<HeartPresenter>
+    {
+    public:
+        HeartCheckView();
+        virtual ~HeartCheckView();
+        static HeartCheckView *GetInstance(void);
+        UIScrollView *HeartCheckViewInit();
+        UIImageAnimatorView *GetImageAnimator();
+        UILabelButton *CreateAndSetUIButton(const char *title);
+        void UpHeartText();
+
+    private:
+        UIImageAnimatorView *imageAnimator;
+        UILabel *titleLabel;
+        UILabel *HeartText;
+        UIScrollView *HeartCheckScrollView;
+        UILabelButton *testButton;
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
index e073bce..59aa389 100644 (file)
@@ -8,54 +8,60 @@
 #include "MainClockView.h"\r
 \r
 #ifdef __cplusplus\r
-extern "C" {\r
+extern "C"\r
+{\r
 #endif\r
 \r
-int PushOHOSMsgToHeartModel(Request *request);\r
-void HeartDataSubscribeTopic(Topic topic);\r
-void HearDatatUnsubscribeTopic(Topic topic);\r
+    int PushOHOSMsgToHeartModel(Request *request);\r
+    void HeartDataSubscribeTopic(Topic topic);\r
+    void HearDatatUnsubscribeTopic(Topic topic);\r
 \r
 #define HEART_ALL_POINTS 360\r
 \r
-typedef struct {\r
-    uint16_t x;\r
-    uint16_t y;\r
-    bool flag;\r
-} Point;\r
-\r
-typedef struct {\r
-    /** X coordinate */\r
-    uint16_t x;\r
-    /** Y coordinate */\r
-    uint16_t y;\r
-} HeartPoint;\r
-\r
-typedef struct {\r
-    uint16_t perSec;\r
-    uint16_t rest;\r
-    uint16_t minX;\r
-    uint16_t minValue;\r
-    uint16_t maxX;\r
-    uint16_t maxValue;\r
-    uint16_t index;\r
-    Point value[HEART_ALL_POINTS];\r
-} HeartInfo;\r
+    typedef struct\r
+    {\r
+        uint16_t x;\r
+        uint16_t y;\r
+        bool flag;\r
+    } Point;\r
+\r
+    typedef struct\r
+    {\r
+        /** X coordinate */\r
+        uint16_t x;\r
+        /** Y coordinate */\r
+        uint16_t y;\r
+    } HeartPoint;\r
+\r
+    typedef struct\r
+    {\r
+        uint16_t perSec;\r
+        uint16_t rest;\r
+        uint16_t minX;\r
+        uint16_t minValue;\r
+        uint16_t maxX;\r
+        uint16_t maxValue;\r
+        uint16_t index;\r
+        Point value[HEART_ALL_POINTS];\r
+    } HeartInfo;\r
 \r
 #pragma pack(4)\r
-typedef struct {\r
-    uint16_t perSec;\r
-    uint16_t rest;\r
-    uint16_t minX;\r
-    uint16_t minValue;\r
-    uint16_t maxX;\r
-    uint16_t maxValue;\r
-    uint16_t index;\r
-    HeartPoint value[HEART_ALL_POINTS];\r
-} HeartDatas;\r
+    typedef struct\r
+    {\r
+        uint16_t perSec;\r
+        uint16_t rest;\r
+        uint16_t minX;\r
+        uint16_t minValue;\r
+        uint16_t maxX;\r
+        uint16_t maxValue;\r
+        uint16_t index;\r
+        HeartPoint value[HEART_ALL_POINTS];\r
+    } HeartDatas;\r
 \r
 #pragma pack()\r
 \r
-namespace OHOS {\r
+    namespace OHOS\r
+    {\r
 #define HEART_AVE_NUM 360\r
 #define HEART_RATE_LIMIT_UPPER 200\r
 #define HEART_RATE_LIMIT_LOWER 0\r
@@ -70,51 +76,83 @@ namespace OHOS {
 #define NUM_16 16\r
 #define NUM_99 99\r
 \r
-typedef struct {\r
-    uint32_t heartRatePerSec;\r
-    Point heartRateAvg[HEART_AVE_NUM];\r
-    uint32_t heartRateRest;\r
-    Point heartRateMax;\r
-    Point heartRateMin;\r
-} HealthAllDatas;\r
-\r
-class HeartModel {\r
-public:\r
-    HeartModel();\r
-    ~HeartModel();\r
-    static HeartModel *GetInstance(void);\r
-    void ObtainingHeartRateData(void);\r
-    void PushHealthDatas(HealthMsg healthMsg);\r
-    Point* GetAveHeartRate(void);\r
-    uint16_t GetAveHeartRateCount(void);\r
-    void SetAveHeartRateCount(uint16_t value);\r
-    Point* GetMaximumHeartRate(void);\r
-    void Init(void);\r
-    void HeartRatePros(HeartDatas *heartInfo);\r
-    void RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate);\r
-    void ClearHeartData(void);\r
-    void HandleMaxHeart(uint16_t coord, uint16_t value);\r
-    void HandleMinHeart(uint16_t coord, uint16_t value);\r
-    void SetHeartRatePerSec(uint32_t sec);\r
-    void SetWearStatus(bool status);\r
-    bool GetWearStatus(void);\r
-    uint16_t GetHeartRateMax(void);\r
-    uint16_t GetHeartRateMin(void);\r
-\r
-private:\r
-    HealthAllDatas healthDatas;\r
-    uint16_t pretime{0};\r
-    uint16_t entryTimes{0};\r
-    uint16_t aveCount{0};\r
-    uint16_t preMaxValue{0};\r
-    uint16_t preMaxX{NUM_1};\r
-    uint16_t preMinValue{HEART_RATE_LIMIT_UPPER};\r
-    uint16_t preMinX{NUM_1};\r
-    uint16_t countMax{0};\r
-    uint16_t countMin{0};\r
-    bool wearStatus{false};\r
-};\r
-}\r
+        typedef struct\r
+        {\r
+            uint32_t heartRatePerSec;\r
+            Point heartRateAvg[HEART_AVE_NUM];\r
+            uint32_t heartRateRest;\r
+            Point heartRateMax;\r
+            Point heartRateMin;\r
+        } HealthAllDatas;\r
+\r
+        class HeartModel\r
+        {\r
+        public:\r
+            HeartModel();\r
+            ~HeartModel();\r
+            static HeartModel *GetInstance(void);\r
+            void ObtainingHeartRateData(void);\r
+            void PushHealthDatas(HealthMsg healthMsg);\r
+            Point *GetAveHeartRate(void);\r
+            uint16_t GetAveHeartRateCount(void);\r
+            void SetAveHeartRateCount(uint16_t value);\r
+            Point *GetMaximumHeartRate(void);\r
+            void Init(void);\r
+            void HeartRatePros(HeartDatas *heartInfo);\r
+            void RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate);\r
+            void ClearHeartData(void);\r
+            void HandleMaxHeart(uint16_t coord, uint16_t value);\r
+            void HandleMinHeart(uint16_t coord, uint16_t value);\r
+            void SetHeartRatePerSec(uint32_t sec);\r
+            void SetWearStatus(bool status);\r
+            bool GetWearStatus(void);\r
+            uint16_t GetHeartRateMax(void);\r
+            uint16_t GetHeartRateMin(void);\r
+\r
+            bool GetHeartViewStatus(void);\r
+            bool GetHeartBandoffViewStatus(void);\r
+            bool GetHeartCheckViewStatus(void);\r
+            void SetHeartViewStatus(bool HeartViewStatus);\r
+            void SetHeartBandoffViewStatus(bool bandoffViewStatus);\r
+            void SetHeartCheckViewStatus(bool checkViewStatus);\r
+\r
+            bool GetCheckStatus();\r
+            void SetCheckStatus(bool checkstatus);\r
+            void UpHeartdata(uint16_t heart);\r
+\r
+            uint16_t GetHeartdata();\r
+            uint16_t GetShowHeartdata();\r
+            uint16_t GetCheckTime();          // 获取距离上传测试时间\r
+            void SetCheckTime(uint16_t time); // 设置本次测试完的时间\r
+            uint16_t GetIndex();              // 测试点位\r
+            void SetIndex(uint16_t index);\r
+\r
+        private:\r
+            HealthAllDatas healthDatas;\r
+            uint16_t pretime{0};\r
+            uint16_t entryTimes{0};\r
+            uint16_t aveCount{0};\r
+            uint16_t preMaxValue{0};\r
+            uint16_t preMaxX{NUM_1};\r
+            uint16_t preMinValue{HEART_RATE_LIMIT_UPPER};\r
+            uint16_t preMinX{NUM_1};\r
+            uint16_t countMax{0};\r
+            uint16_t countMin{0};\r
+            bool wearStatus{false};\r
+            uint16_t index_ = 0;\r
+\r
+            bool HeartView;\r
+            bool BandoffView;\r
+            bool CheckView;\r
+            bool ResultView;\r
+            bool CheckStatus;     // 检测状态标志\r
+            uint16_t Show_Heart_; // 显示血氧\r
+            uint16_t Heart_;      // 保存血氧\r
+            uint16_t TIME_;       // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)\r
+\r
+            bool initstatus = true;\r
+        };\r
+    }\r
 \r
 #ifdef __cplusplus\r
 }\r
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartPresenter.h
new file mode 100644 (file)
index 0000000..213e4e8
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodOxygen view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef HEART_PRESENTER_H
+#define HEART_PRESENTER_H
+
+#include "Presenter.h"
+#include "ModelListenerSample.h"
+#include "components/ui_circle_progress.h"
+#include "ohos_types.h"
+#include "KeyInputListener.h"
+#include "common/key_code.h"
+
+namespace OHOS
+{
+
+    typedef enum
+    {
+        HEARTVIEW = 0,  // 血氧视图(slice)
+        HEARTBANDVIEW,
+        HEARTCHECKVIEW, // 检测视图(subView)
+        HEARTRESULT,    // 测试失败(subView)
+        MAX_HEARTVIEW,
+    } HEARTVIEWID;
+
+    class HeartView;
+    class HeartPresenter : public Presenter<HeartView>,
+                                 public UIView::OnClickListener,
+                                 public RootView::OnKeyActListener,
+                                 public ModelListenerSample,
+                                 public UIView::OnDragListener
+    {
+    public:
+        HeartPresenter();
+        virtual ~HeartPresenter();
+
+        void OnStart() override;
+        void OnPause() override;
+        void OnResume() override;
+        void OnStop() override;
+        virtual void Notify() override;
+        static HeartPresenter *GetInstance(void);
+        bool OnDrag(UIView &view, const DragEvent &event) override;
+        bool OnDragEnd(UIView &view, const DragEvent &event) override;
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
+
+        uint16_t GetCurrentTime();
+        std::string GetTDOA(uint16_t new_time, uint16_t old_time);
+
+    private:
+        bool CheckPointersValue(void);
+        void ReturnInterface(void);
+        void ProgressNotify(void);
+        int count;
+        bool startheart = true;
+        KeyInputListener *keyActListenr{nullptr};
+    };
+}
+
+#endif
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartResultView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartResultView.h
new file mode 100644 (file)
index 0000000..6b8a48e
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: bloodResult view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef HEART_Result_VIEW_H
+#define HEART_Result_VIEW_H
+
+#include "View.h"
+#include "BaseView.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "components/ui_label.h"
+#include "components/ui_button.h"
+#include "components/ui_label_button.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_view_group.h"
+#include "HeartPresenter.h"
+#include "components/ui_scroll_view.h"
+namespace OHOS
+{
+    class HeartPresenter;
+    class HeartBandoffView;
+
+    class HeartResultView : public View<HeartPresenter>
+    {
+    public:
+        HeartResultView();
+        virtual ~HeartResultView();
+        static HeartResultView *GetInstance(void);
+        UIScrollView *HeartResultViewInit();
+    private:
+        // 增加图片
+        bool InitImageDisplay(void);
+        // 初始化标签
+        bool InitLabel(void);
+        HeartResultView *bloodresult{nullptr};
+        UIImageView *imageerror; // 图片
+        UILabel *titlelabel;
+        UILabel *label1;
+        UILabel *label2;
+        UILabel *label3;
+
+        UIScrollView *HeartResultScrollView;
+        UILabelButton *ReButton;
+        UILabelButton *StButton;
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartView.h
new file mode 100644 (file)
index 0000000..0869abb
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: heart view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#ifndef HEART_VIEW_H
+#define HEART_VIEW_H
+
+#include "View.h"
+#include "BaseView.h"
+#include "wearable_log.h"
+#include "UiConfig.h"
+#include "components/ui_label.h"
+#include "components/ui_button.h"
+#include "components/ui_label_button.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_view_group.h"
+#include "components/ui_scroll_view.h"
+#include "HeartPresenter.h"
+#include "HeartCheckView.h"
+#include "HeartResultView.h"
+#include "power_display_service.h"
+namespace OHOS
+{
+    class HeartPresenter;
+    //class HeartBandoffView;
+    class HeartCheckView;
+    class HeartResultView;
+    class HeartView : public View<HeartPresenter>
+    {
+    public:
+        HeartView();
+        virtual ~HeartView();
+
+        void OnStop() override;
+        void OnSetUpView() override;
+        void OnTearDownView() override;
+        void OnStart() override;
+        static HeartView *GetInstance(void);
+        bool ChangeHeartView(int16_t thisview); // 主视图
+        bool ChangeCheckView(int16_t thisview);
+        bool ChangeResultView(int16_t thisview);
+
+        bool ClickFunc(int16_t interface);
+        void ChangeView(int16_t hideView, int16_t showView);
+        UIScrollView *GetHeartScrollView(int ViewId);
+        void Upheartdata();
+
+    private:
+        // 增加图片
+        bool InitImageDisplay(void);
+        // 初始化标签
+        bool InitLabel(void);
+        // 添加label按键
+        UILabelButton *CreateAndSetUIButton(const char *title);
+        // 初始化界面
+        bool InitHeartView(void);
+        bool SetOnDragListener(void);
+
+        HeartCheckView *heartcheck{nullptr};
+        HeartResultView *heartresult{nullptr};
+        UIScrollView *HeartScrollView[4]{nullptr};
+
+        UIViewGroup *group;
+        UIImageView *imageViewMain; // 背景图片
+        UILabel *percent;           // 心率值
+        UILabel *timeLabel;         // 检测时间
+        UILabel *titleLabel;        // 页面title
+        UILabelButton *testButton;  // 检测按键
+
+        const power_display_svr_api_t *display_api = power_display_svr_get_api();
+        uint32_t display_time;
+        uint32_t heart_;
+    };
+}
+
+#endif // 血氧主界面
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartBandoffView.cpp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartCheckView.cpp
new file mode 100644 (file)
index 0000000..ab72cc0
--- /dev/null
@@ -0,0 +1,172 @@
+
+
+#include "UiConfig.h"
+#include "wearable_log.h"
+#include "HeartCheckView.h"
+#include "HeartModel.h"
+#include "ui_image_animator.h"
+#include "HeartCheckView.h"
+namespace OHOS
+{
+    // 动态刷新设置
+    static constexpr uint16_t IMAGE_SIZE = 180;
+    static constexpr uint16_t IMAGE_POSITION_Y = 134;
+    static constexpr uint16_t IMAGE_POSITION_X = 150;
+    static constexpr uint16_t CHECKIMAGEANIMATORVIEW_SIZE = 20;
+    static constexpr uint16_t CHECKIMAGEANIMATORVIEW_SPEED = 40;
+
+    static ImageAnimatorInfo g_imageAnimatorInfo_Time[20] = {
+        {PNG_CHECK_TIME_IMAGE_0, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_1, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_2, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_3, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_4, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_5, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_6, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_7, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_8, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_9, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_10, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_11, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_12, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_13, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_14, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_15, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_16, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_17, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_18, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+        {PNG_CHECK_TIME_IMAGE_19, {IMAGE_POSITION_X, IMAGE_POSITION_Y}, IMAGE_SIZE, IMAGE_SIZE, IMG_SRC_FILE_PATH},
+    };
+
+    static HeartCheckView *g_pMainView = nullptr;
+    HeartCheckView::HeartCheckView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::HeartBandoffView");
+        titleLabel = nullptr;
+        HeartCheckScrollView = nullptr;
+        imageAnimator = nullptr;
+        testButton = nullptr;
+        g_pMainView = this;
+    }
+
+    HeartCheckView *HeartCheckView::GetInstance(void)
+    {
+        return g_pMainView;
+    }
+
+    UIImageAnimatorView *HeartCheckView::GetImageAnimator()
+    {
+        return imageAnimator;
+    }
+
+    HeartCheckView::~HeartCheckView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartCheckView::~HeartCheckView");
+        HeartCheckScrollView->RemoveAll();
+        delete titleLabel;
+        delete testButton;
+        delete HeartCheckScrollView;
+        delete imageAnimator;
+        delete HeartText;
+        titleLabel = nullptr;
+        HeartCheckScrollView = nullptr;
+        imageAnimator = nullptr;
+        testButton = nullptr;
+        HeartText = nullptr;
+        g_pMainView = this;
+    }
+    void HeartCheckView::UpHeartText()
+    {
+        uint16_t heart_ = HeartModel::GetInstance()->GetShowHeartdata();
+        // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetHeartData %d", heart_);
+        std::string bloodoxygenStr = std::to_string(heart_);
+        HeartText->SetText(bloodoxygenStr.c_str());
+    }
+    UIScrollView *HeartCheckView::HeartCheckViewInit()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartCheckView::CreateUIViewHeartCheckScrollView");
+        HeartCheckScrollView = new UIScrollView();
+        if (HeartCheckScrollView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new HeartCheckScrollView fail");
+            return nullptr;
+        }
+        HeartCheckScrollView->SetPosition(0, 0);
+        HeartCheckScrollView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION);
+        /* -------------------------------------------------------------------------- */
+        titleLabel = new UILabel();
+        if (titleLabel == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new titleLabel fail");
+            return nullptr;
+        }
+        titleLabel->SetPosition(175, 55); // widget's left position and top position
+        titleLabel->Resize(200, 90);      // widget's width and height
+        titleLabel->SetViewId("label3");  // Set style
+        titleLabel->SetStyle(STYLE_TEXT_FONT, 28);
+        titleLabel->SetText("正在检测");
+        titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        titleLabel->SetRollSpeed(0);
+        titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 28);
+        HeartCheckScrollView->Add(titleLabel);
+        /* -------------------------------------------------------------------------- */
+
+        imageAnimator = new UIImageAnimatorView();
+        if (imageAnimator == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new UIImageAnimatorView fail");
+            return nullptr;
+        }
+        imageAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_Time, CHECKIMAGEANIMATORVIEW_SIZE, CHECKIMAGEANIMATORVIEW_SPEED);
+        imageAnimator->SetRepeatTimes(20);
+        imageAnimator->SetRepeat(false);
+        imageAnimator->Start();
+        HeartCheckScrollView->Add(imageAnimator);
+        /* -------------------------------------------------------------------------- */
+        if (testButton == nullptr)
+        {
+            testButton = new UILabelButton();
+        }
+        testButton->SetPosition(118, 336);    // widget's left position and top position
+        testButton->Resize(230, 80);          // widget's width and height
+        testButton->SetViewId("labelButton"); // Set style
+        testButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+
+        // Set additional property
+        testButton->SetText("停止检测");
+        testButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        testButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED);
+        testButton->SetViewId("checkstop");
+        UIView::OnClickListener *clickLeftListener = (UIView::OnClickListener *)OHOS::HeartPresenter::GetInstance();
+        if (clickLeftListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new clickLeftListener fail");
+            return nullptr;
+        }
+        testButton->SetOnClickListener(clickLeftListener);
+        HeartCheckScrollView->Add(testButton);
+        /* -------------------------------------------------------------------------- */
+        HeartText = new UILabel();
+        if (HeartText == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new HeartText fail");
+            return nullptr;
+        }
+        HeartText->SetPosition(133, 110); // widget's left position and top position
+        HeartText->Resize(200, 200);      // widget's width and height
+        HeartText->SetViewId("label");    // Set style
+        HeartText->SetStyle(STYLE_TEXT_FONT, 140);
+        uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetHeartData %d", heart_);
+        std::string bloodoxygenStr = std::to_string(heart_);
+        HeartText->SetText(bloodoxygenStr.c_str());
+        HeartText->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+        HeartText->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        HeartText->SetRollSpeed(0);
+        HeartText->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 140);
+        HeartCheckScrollView->Add(HeartText);
+        /* -------------------------------------------------------------------------- */
+        return HeartCheckScrollView;
+    }
+}
index a56deb9..99f6124 100644 (file)
 #include "IndoorWalkPresenter.h"\r
 #include "MainViewSample.h"\r
 #include "HeartRateView.h"\r
-\r
+#include <iostream>\r
+#include <random>\r
+#include "heartrate/include/HeartView.h"\r
+#include "heartrate/include/HeartPresenter.h"\r
+#include "DialModelHeartRate.h"\r
 #ifdef __cplusplus\r
-extern "C" {\r
+extern "C"\r
+{\r
 #endif\r
 \r
-/* 佩戴检测结果 */\r
-enum {\r
-    SENSOR_WEAR_ON = 0,\r
-    SENSOR_WEAR_OFF,\r
-    SENSOR_WEAR_UNKNOW,\r
-    SENSOR_WEAR_MAX\r
-};\r
+    /* 佩戴检测结果 */\r
+    enum\r
+    {\r
+        SENSOR_WEAR_ON = 0,\r
+        SENSOR_WEAR_OFF,\r
+        SENSOR_WEAR_UNKNOW,\r
+        SENSOR_WEAR_MAX\r
+    };\r
 \r
-using namespace OHOS;\r
+    using namespace OHOS;\r
 #define LEN 32\r
 \r
-static void Notify(void *args, const Topic topic, Request* request);\r
+    static void Notify(void *args, const Topic topic, Request *request);\r
 \r
-Subscriber heartSubscirber = {\r
-    .identity = NULL,\r
-    .args = NULL,\r
-    .Notify = Notify,\r
-};\r
-\r
-void HeartDataSubscribeTopic(Topic topic)\r
-{\r
-    BroadcastApi *broadcastApi = NULL;\r
-    IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
-    if (api == NULL) {\r
-        return;\r
-    }\r
-    int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
-    if (result != 0 || broadcastApi == NULL) {\r
-        return;\r
-    }\r
-    int ret = broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartSubscribeTopic ret = %d, topic = %u", ret, topic);\r
-    broadcastApi->Release((IUnknown *)broadcastApi);\r
-}\r
+    Subscriber heartSubscirber = {\r
+        .identity = NULL,\r
+        .args = NULL,\r
+        .Notify = Notify,\r
+    };\r
 \r
-void HearDatatUnsubscribeTopic(Topic topic)\r
-{\r
-    BroadcastApi *broadcastApi = NULL;\r
-    IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
-    if (api == NULL) {\r
-        return;\r
-    }\r
-    int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
-    if (result != 0 || broadcastApi == NULL) {\r
-        return;\r
+    void HeartDataSubscribeTopic(Topic topic)\r
+    {\r
+        BroadcastApi *broadcastApi = NULL;\r
+        IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
+        if (api == NULL)\r
+        {\r
+            return;\r
+        }\r
+        int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
+        if (result != 0 || broadcastApi == NULL)\r
+        {\r
+            return;\r
+        }\r
+        int ret = broadcastApi->SubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartSubscribeTopic ret = %d, topic = %u", ret, topic);\r
+        broadcastApi->Release((IUnknown *)broadcastApi);\r
     }\r
-    broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
-    broadcastApi->Release((IUnknown *)broadcastApi);\r
-}\r
 \r
-static void Notify(void *args, const Topic topic, Request* request)\r
-{\r
-    UNUSED(args);\r
-    UNUSED(topic);\r
-    if (request == NULL) {\r
-        return;\r
-    }\r
-    if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA) {\r
-        HeartDatas *heartInfo = (HeartDatas*)malloc(sizeof(HeartDatas));\r
-        if (heartInfo == NULL) {\r
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Notify] malloc fail");\r
+    void HearDatatUnsubscribeTopic(Topic topic)\r
+    {\r
+        BroadcastApi *broadcastApi = NULL;\r
+        IUnknown *api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
+        if (api == NULL)\r
+        {\r
+            return;\r
         }\r
-\r
-        int rets = memcpy_s(heartInfo, sizeof(HeartDatas), (HeartInfo*)request->data, request->len);\r
-        if (rets != EOK) {\r
-            free(heartInfo);\r
-            heartInfo = NULL;\r
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s heartRateData fail! ret = %d", rets);\r
+        int result = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
+        if (result != 0 || broadcastApi == NULL)\r
+        {\r
             return;\r
         }\r
-\r
-        OHOS::HeartModel::GetInstance()->HeartRatePros(heartInfo);\r
-\r
-        free(heartInfo);\r
-        heartInfo = NULL;\r
-    }\r
-    if (request->msgId == TOPIC_EVENT_NEXTDAY_UPDATE) {\r
-        OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+        broadcastApi->UnsubscribeTopic((IUnknown *)broadcastApi, topic, &heartSubscirber);\r
+        broadcastApi->Release((IUnknown *)broadcastApi);\r
     }\r
-    if (request->msgId == TOPIC_EVENT_UTCTIME_UPDATE) {\r
-        OHOS::HeartModel::GetInstance()->ClearHeartData();\r
-    }\r
-    if (request->msgId == TOPIC_EVENT_WEARSTATE_UPDATE) {\r
-        uint32 wearStatus = *((uint32*)request->data);\r
-        if (wearStatus == SENSOR_WEAR_OFF) {\r
-            OHOS::HeartModel::GetInstance()->SetWearStatus(false);\r
-            OHOS::HeartModel::GetInstance()->SetHeartRatePerSec(0);\r
-            if (OHOS::MainClockView::GetInstance() != nullptr) {\r
-                OHOS::MainClockView::GetInstance()->RefreshHeartRate(0);\r
+\r
+    static void Notify(void *args, const Topic topic, Request *request)\r
+    {\r
+        UNUSED(args);\r
+        UNUSED(topic);\r
+        if (request == NULL)\r
+        {\r
+            return;\r
+        }\r
+        if (request->msgId == TOPIC_EVENT_HEARTRATE_UPDATA)\r
+        {\r
+#if 0\r
+            int rets = memcpy_s(heartInfo, sizeof(HeartDatas), (HeartInfo *)request->data, request->len);\r
+            if (rets != EOK)\r
+            {\r
+                free(heartInfo);\r
+                heartInfo = NULL;\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "memcpy_s heartRateData fail! ret = %d", rets);\r
+                return;\r
+            }\r
+#endif\r
+            uint16_t preheart = *(uint16_t *)request->data;\r
+            // 筛选出正常数据\r
+            if (preheart > HEART_RATE_LIMIT_LOWER && preheart <= HEART_RATE_LIMIT_UPPER)\r
+            {\r
+                uint16_t index_ = HeartModel::GetInstance()->GetIndex();\r
+                HeartDatas *heartInfo = (HeartDatas *)malloc(sizeof(HeartDatas));\r
+                if (heartInfo == NULL)\r
+                {\r
+                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[Notify] malloc fail");\r
+                }\r
+                heartInfo->index = index_;\r
+                heartInfo->maxX = index_;\r
+                heartInfo->minX = index_;\r
+                heartInfo->perSec = preheart;\r
+                heartInfo->rest = preheart;\r
+                heartInfo->maxValue = preheart;\r
+                heartInfo->minValue = preheart;\r
+                heartInfo->value[index_].x = index_;\r
+                heartInfo->value[index_].y = preheart;\r
+                index_++;\r
+                if (index_ == HEART_ALL_POINTS)\r
+                {\r
+                    index_ = 0;\r
+                }\r
+                HeartModel::GetInstance()->SetIndex(index_);\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartRateData = %d %d", heartInfo->index, preheart);\r
+                OHOS::HeartModel::GetInstance()->HeartRatePros(heartInfo);\r
+                free(heartInfo);\r
+                heartInfo = NULL;\r
+            }\r
+        }\r
+        if (request->msgId == TOPIC_EVENT_NEXTDAY_UPDATE)\r
+        {\r
+            OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+        }\r
+        if (request->msgId == TOPIC_EVENT_UTCTIME_UPDATE)\r
+        {\r
+            OHOS::HeartModel::GetInstance()->ClearHeartData();\r
+        }\r
+        if (request->msgId == TOPIC_EVENT_WEARSTATE_UPDATE)\r
+        {\r
+            uint32 wearStatus = *((uint32 *)request->data);\r
+            if (wearStatus == SENSOR_WEAR_OFF)\r
+            {\r
+                OHOS::HeartModel::GetInstance()->SetWearStatus(false);\r
+                OHOS::HeartModel::GetInstance()->SetHeartRatePerSec(0);\r
+                if (OHOS::MainClockView::GetInstance() != nullptr)\r
+                {\r
+                    // OHOS::MainClockView::GetInstance()->RefreshHeartRate(*(uint16_t *)request->data);\r
+                }\r
+            }\r
+            else\r
+            {\r
+                OHOS::HeartModel::GetInstance()->SetWearStatus(true);\r
             }\r
-        } else {\r
-            OHOS::HeartModel::GetInstance()->SetWearStatus(true);\r
         }\r
     }\r
-}\r
 \r
 #ifdef __cplusplus\r
 }\r
 #endif\r
 \r
-namespace OHOS {\r
-void HeartModel::ClearHeartData(void)\r
+namespace OHOS\r
 {\r
-    pretime = 0;\r
-    entryTimes = 0;\r
-    aveCount = 0;\r
-    preMaxValue = 0;\r
-    preMaxX = NUM_1;\r
-    preMinValue = HEART_RATE_LIMIT_UPPER;\r
-    preMinX = NUM_1;\r
-    countMax = 0;\r
-    countMin = 0;\r
-    healthDatas.heartRateMax.x = (uint16_t)0XFFFF;\r
-    healthDatas.heartRateMax.y = 0;\r
-    healthDatas.heartRateMin.x = (uint16_t)0XFFFF;\r
-    healthDatas.heartRateMin.y = (uint16_t)0XFFFF;\r
-    for (int i = 0; i < HEART_AVE_NUM; i++) {\r
-        healthDatas.heartRateAvg[i].x = (uint16_t)0XFFFF;\r
-        healthDatas.heartRateAvg[i].y = (uint16_t)0XFFFF;\r
-    }\r
-    if (HeartRateView::GetInstance() != nullptr) {\r
-        HeartRateView::GetInstance()->ClearElectrocardiogram();\r
-    }\r
-    SetAveHeartRateCount(0);\r
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
-        healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
-}\r
+    void HeartModel::ClearHeartData(void)\r
+    {\r
+        pretime = 0;\r
+        entryTimes = 0;\r
+        aveCount = 0;\r
+        preMaxValue = 0;\r
+        preMaxX = NUM_1;\r
+        preMinValue = HEART_RATE_LIMIT_UPPER;\r
+        preMinX = NUM_1;\r
+        countMax = 0;\r
+        countMin = 0;\r
+        healthDatas.heartRateMax.x = (uint16_t)0XFFFF;\r
+        healthDatas.heartRateMax.y = 0;\r
+        healthDatas.heartRateMin.x = (uint16_t)0XFFFF;\r
+        healthDatas.heartRateMin.y = (uint16_t)0XFFFF;\r
+        for (int i = 0; i < HEART_AVE_NUM; i++)\r
+        {\r
+            healthDatas.heartRateAvg[i].x = (uint16_t)0XFFFF;\r
+            healthDatas.heartRateAvg[i].y = (uint16_t)0XFFFF;\r
+        }\r
+        if (HeartRateView::GetInstance() != nullptr)\r
+        {\r
+            HeartRateView::GetInstance()->ClearElectrocardiogram();\r
+        }\r
+        SetAveHeartRateCount(0);\r
+        GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
+                                                                  healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
+    }\r
 \r
-HeartModel::HeartModel()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartModel()");\r
-}\r
+    HeartModel::HeartModel()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartModel()");\r
+        HeartView = false;\r
+        BandoffView = false;\r
+        CheckView = false;\r
+        ResultView = false;\r
+        CheckStatus = false;\r
+        // 初始化血氧值\r
+        Heart_ = DialModelHeartRate::GetInstance()->GetHeartData();\r
+    }\r
 \r
-HeartModel::~HeartModel()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::~HeartModel()");\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
-    HearDatatUnsubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
-}\r
+    HeartModel::~HeartModel()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::~HeartModel()");\r
+        HearDatatUnsubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
+        HearDatatUnsubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
+        HearDatatUnsubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
+        HearDatatUnsubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
+    }\r
 \r
-HeartModel *HeartModel::GetInstance(void)\r
-{\r
-    static HeartModel heartModel;\r
-    return &heartModel;\r
-}\r
+    HeartModel *HeartModel::GetInstance(void)\r
+    {\r
+        static HeartModel heartModel;\r
+        return &heartModel;\r
+    }\r
+    uint16_t HeartModel::GetIndex()\r
+    {\r
+        return index_;\r
+    }\r
+    void HeartModel::SetIndex(uint16_t index)\r
+    {\r
+        index_ = index;\r
+    }\r
 \r
-void HeartModel::Init(void)\r
-{\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
-    HeartDataSubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
-}\r
+    void HeartModel::Init(void)\r
+    {\r
+        HeartDataSubscribeTopic(TOPIC_EVENT_HEARTRATE_UPDATA);\r
+        HeartDataSubscribeTopic(TOPIC_EVENT_NEXTDAY_UPDATE);\r
+        HeartDataSubscribeTopic(TOPIC_EVENT_UTCTIME_UPDATE);\r
+        HeartDataSubscribeTopic(TOPIC_EVENT_WEARSTATE_UPDATE);\r
+    }\r
 \r
-Point* HeartModel::GetAveHeartRate(void)\r
-{\r
-    return healthDatas.heartRateAvg;\r
-}\r
+    Point *HeartModel::GetAveHeartRate(void)\r
+    {\r
+        return healthDatas.heartRateAvg;\r
+    }\r
 \r
-void HeartModel::HandleMaxHeart(uint16 coord, uint16 value)\r
-{\r
-    healthDatas.heartRateMax.x = coord;\r
-    healthDatas.heartRateMax.y = value;\r
-    // 插入最大心率 countMax 数据个数\r
-    if (preMaxValue != healthDatas.heartRateMax.y && aveCount < HEART_AVE_NUM) {\r
-        if (preMaxX == healthDatas.heartRateMax.x && countMax < HEART_AVE_NUM) {\r
-            healthDatas.heartRateAvg[countMax].y = healthDatas.heartRateMax.y;\r
-        } else if (aveCount > NUM_2 && (healthDatas.heartRateMax.x == healthDatas.heartRateAvg[aveCount - 1].x)) {\r
-            healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMax.y;\r
-        } else {\r
-            healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMax;\r
-            countMax = aveCount;\r
-            aveCount++;\r
-        }\r
-        if (healthDatas.heartRateMax.x != 0) {\r
-            if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0) {\r
-                for (int i = 1; i < (aveCount - 1); i++) {\r
-                    healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
+    void HeartModel::HandleMaxHeart(uint16 coord, uint16 value)\r
+    {\r
+        healthDatas.heartRateMax.x = coord;\r
+        healthDatas.heartRateMax.y = value;\r
+        // 插入最大心率 countMax 数据个数\r
+        if (preMaxValue != healthDatas.heartRateMax.y && aveCount < HEART_AVE_NUM)\r
+        {\r
+            if (preMaxX == healthDatas.heartRateMax.x && countMax < HEART_AVE_NUM)\r
+            {\r
+                healthDatas.heartRateAvg[countMax].y = healthDatas.heartRateMax.y;\r
+            }\r
+            else if (aveCount > NUM_2 && (healthDatas.heartRateMax.x == healthDatas.heartRateAvg[aveCount - 1].x))\r
+            {\r
+                healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMax.y;\r
+            }\r
+            else\r
+            {\r
+                healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMax;\r
+                countMax = aveCount;\r
+                aveCount++;\r
+            }\r
+            if (healthDatas.heartRateMax.x != 0)\r
+            {\r
+                if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0)\r
+                {\r
+                    for (int i = 1; i < (aveCount - 1); i++)\r
+                    {\r
+                        healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
+                    }\r
+                    aveCount--;\r
+                    countMax--;\r
                 }\r
-                aveCount--;\r
-                countMax--;\r
             }\r
         }\r
+        preMaxValue = healthDatas.heartRateMax.y;\r
+        preMaxX = healthDatas.heartRateMax.x;\r
     }\r
-    preMaxValue = healthDatas.heartRateMax.y;\r
-    preMaxX = healthDatas.heartRateMax.x;\r
-}\r
 \r
-void HeartModel::HandleMinHeart(uint16 coord, uint16 value)\r
-{\r
-    // 最小心率\r
-    healthDatas.heartRateMin.x = coord;\r
-    healthDatas.heartRateMin.y = value;\r
-    // 插入最小心率\r
-    //avecount 当下有效数据个数,在MaxHeart中也用到,看起来似乎有问题???\r
-    //preMinValue 上一个心率最小值\r
-    //preMinX 上一个最小值对应的坐标\r
-    //当上一个值与当前值不等,且没有超过总数限制,则进行数据处理\r
-    if (preMinValue != healthDatas.heartRateMin.y && aveCount < HEART_AVE_NUM) {\r
-\r
-        \r
-        if (preMinX == healthDatas.heartRateMin.x && countMin < HEART_AVE_NUM) {\r
-            // 上一个最小坐标和当前值一致,且数据没超过限制,则直接赋值给有效数据 countMin 即可\r
-            healthDatas.heartRateAvg[countMin].y = healthDatas.heartRateMin.y;\r
-        } else if (aveCount > NUM_2 && (healthDatas.heartRateMin.x == healthDatas.heartRateAvg[aveCount - 1].x)) {\r
-            //有效数据大于2,且当前x值与原始数据最后一个x一致,最后一个数据赋值\r
-            healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMin.y;\r
-        } else {\r
-            healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMin;\r
-            countMin = aveCount;\r
-            aveCount++;\r
-        }\r
+    void HeartModel::HandleMinHeart(uint16 coord, uint16 value)\r
+    {\r
+        // 最小心率\r
+        healthDatas.heartRateMin.x = coord;\r
+        healthDatas.heartRateMin.y = value;\r
+        // 插入最小心率\r
+        // avecount 当下有效数据个数,在MaxHeart中也用到,看起来似乎有问题???\r
+        // preMinValue 上一个心率最小值\r
+        // preMinX 上一个最小值对应的坐标\r
+        // 当上一个值与当前值不等,且没有超过总数限制,则进行数据处理\r
+        if (preMinValue != healthDatas.heartRateMin.y && aveCount < HEART_AVE_NUM)\r
+        {\r
+\r
+            if (preMinX == healthDatas.heartRateMin.x && countMin < HEART_AVE_NUM)\r
+            {\r
+                // 上一个最小坐标和当前值一致,且数据没超过限制,则直接赋值给有效数据 countMin 即可\r
+                healthDatas.heartRateAvg[countMin].y = healthDatas.heartRateMin.y;\r
+            }\r
+            else if (aveCount > NUM_2 && (healthDatas.heartRateMin.x == healthDatas.heartRateAvg[aveCount - 1].x))\r
+            {\r
+                // 有效数据大于2,且当前x值与原始数据最后一个x一致,最后一个数据赋值\r
+                healthDatas.heartRateAvg[aveCount - 1].y = healthDatas.heartRateMin.y;\r
+            }\r
+            else\r
+            {\r
+                healthDatas.heartRateAvg[aveCount] = healthDatas.heartRateMin;\r
+                countMin = aveCount;\r
+                aveCount++;\r
+            }\r
 \r
-        //最初的值一直是0 ,则只显示1个 ,不会在后面增加数据。\r
-        if (healthDatas.heartRateMin.x != 0) {\r
-            if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0) {\r
-                for (int i = 0; i < (aveCount - 1); i++) {\r
-                    healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
+            // 最初的值一直是0 ,则只显示1个 ,不会在后面增加数据。\r
+            if (healthDatas.heartRateMin.x != 0)\r
+            {\r
+                if (healthDatas.heartRateAvg[0].x == 0 && healthDatas.heartRateAvg[1].x == 0)\r
+                {\r
+                    for (int i = 0; i < (aveCount - 1); i++)\r
+                    {\r
+                        healthDatas.heartRateAvg[i] = healthDatas.heartRateAvg[i + 1];\r
+                    }\r
+                    aveCount--;\r
+                    countMin--;\r
                 }\r
-                aveCount--;\r
-                countMin--;\r
             }\r
         }\r
+        preMinValue = healthDatas.heartRateMin.y;\r
+        preMinX = healthDatas.heartRateMin.x;\r
     }\r
-    preMinValue = healthDatas.heartRateMin.y;\r
-    preMinX = healthDatas.heartRateMin.x;\r
-}\r
 \r
-void  HeartModel::HeartRatePros(HeartDatas *heartInfo)\r
-{\r
-    uint16_t perSecHeartRate = 0;\r
-    uint16_t restHeartRate = 0;\r
-\r
-    // 每秒心率\r
-    perSecHeartRate = heartInfo->perSec;\r
-    if (perSecHeartRate > HEART_RATE_LIMIT_LOWER && perSecHeartRate <= HEART_RATE_LIMIT_UPPER) {\r
-        healthDatas.heartRatePerSec = perSecHeartRate;\r
-    }\r
-\r
-    // 静息心率\r
-    restHeartRate = heartInfo->rest;\r
-    if (restHeartRate > HEART_RATE_LIMIT_LOWER && restHeartRate <= HEART_RATE_LIMIT_UPPER) {\r
-        healthDatas.heartRateRest = restHeartRate;\r
-    }\r
-    HandleMinHeart(heartInfo->minX, heartInfo->minValue);\r
-    HandleMaxHeart(heartInfo->maxX, heartInfo->maxValue);\r
-    // 平均心率\r
-    uint16_t count = aveCount + heartInfo->index;\r
-    if (aveCount < HEART_AVE_NUM) {\r
-        for (int i = aveCount; i < count; i++) {\r
-            if (healthDatas.heartRateMin.x != heartInfo->value[i - aveCount].x && healthDatas.heartRateMax.x != heartInfo->value[i - aveCount].x) {\r
-                healthDatas.heartRateAvg[aveCount].x = heartInfo->value[i - aveCount].x;\r
-                healthDatas.heartRateAvg[aveCount].y = heartInfo->value[i - aveCount].y;\r
-                aveCount++;\r
+    void HeartModel::HeartRatePros(HeartDatas *heartInfo)\r
+    {\r
+        uint16_t perSecHeartRate = 0;\r
+        uint16_t restHeartRate = 0;\r
+#if 0\r
+        // 使用随机数生成模拟数据\r
+        std::random_device rd;\r
+        std::mt19937 gen(rd());\r
+        std::uniform_int_distribution<> heartRateDist(50, 100);\r
+\r
+        heartInfo->perSec = heartRateDist(gen);\r
+        heartInfo->rest = heartRateDist(gen);\r
+        heartInfo->maxValue = heartRateDist(gen);\r
+        heartInfo->minValue = heartRateDist(gen);\r
+        heartInfo->minX = 1;\r
+        heartInfo->maxX = 10;\r
+        // heartInfo->index = 0;\r
+        heartInfo->value[heartInfo->index].x = 0;\r
+        heartInfo->value[heartInfo->index].y = heartRateDist(gen);\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " heartRateData: %d %d %d %d %d %d %d %d ",\r
+                      heartInfo->perSec, heartInfo->rest, heartInfo->maxValue, heartInfo->minValue, heartInfo->minX, heartInfo->index, heartInfo->value[0].x, heartInfo->value[0].y);\r
+\r
+#endif\r
+        // 每秒心率\r
+        perSecHeartRate = heartInfo->perSec;\r
+        if (perSecHeartRate > HEART_RATE_LIMIT_LOWER && perSecHeartRate <= HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            healthDatas.heartRatePerSec = perSecHeartRate;\r
+        }\r
+\r
+        // 静息心率\r
+        restHeartRate = heartInfo->rest;\r
+        if (restHeartRate > HEART_RATE_LIMIT_LOWER && restHeartRate <= HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            healthDatas.heartRateRest = restHeartRate;\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heartRateRest:%d ", healthDatas.heartRateRest);\r
+        }\r
+        HandleMinHeart(heartInfo->minX, heartInfo->minValue);\r
+        HandleMaxHeart(heartInfo->maxX, heartInfo->maxValue);\r
+        // 平均心率\r
+        uint16_t count = aveCount + heartInfo->index;\r
+        if (aveCount < HEART_AVE_NUM)\r
+        {\r
+            for (int i = aveCount; i < count; i++)\r
+            {\r
+                if (healthDatas.heartRateMin.x != heartInfo->value[i - aveCount].x && healthDatas.heartRateMax.x != heartInfo->value[i - aveCount].x)\r
+                {\r
+                    healthDatas.heartRateAvg[aveCount].x = heartInfo->value[i - aveCount].x;\r
+                    healthDatas.heartRateAvg[aveCount].y = heartInfo->value[i - aveCount].y;\r
+                    aveCount++;\r
+                }\r
             }\r
         }\r
-    }\r
 \r
-    for (int i = 0; i < aveCount - 1; i++) {\r
-        if (healthDatas.heartRateAvg[i].x == healthDatas.heartRateAvg[i + 1].x) {\r
-            if (healthDatas.heartRateAvg[i].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i].y != healthDatas.heartRateMax.y) {\r
-                for (int j = i; j < aveCount - 1; j++) {\r
-                    healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
+        for (int i = 0; i < aveCount - 1; i++)\r
+        {\r
+            if (healthDatas.heartRateAvg[i].x == healthDatas.heartRateAvg[i + 1].x)\r
+            {\r
+                if (healthDatas.heartRateAvg[i].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i].y != healthDatas.heartRateMax.y)\r
+                {\r
+                    for (int j = i; j < aveCount - 1; j++)\r
+                    {\r
+                        healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
+                    }\r
+                    aveCount--;\r
                 }\r
-                aveCount--;\r
-            } else if (healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMax.y) {\r
-                for (int j = i + 1; j < aveCount - 1; j++) {\r
-                    healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
+                else if (healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMin.y && healthDatas.heartRateAvg[i + 1].y != healthDatas.heartRateMax.y)\r
+                {\r
+                    for (int j = i + 1; j < aveCount - 1; j++)\r
+                    {\r
+                        healthDatas.heartRateAvg[j] = healthDatas.heartRateAvg[j + 1];\r
+                    }\r
+                    aveCount--;\r
                 }\r
-                aveCount--;\r
             }\r
         }\r
+        GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
+                                                                  healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
     }\r
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&HeartModel::RefreshHeartRateScreen, HeartModel::GetInstance(),\r
-        healthDatas.heartRatePerSec, healthDatas.heartRateRest, healthDatas.heartRateMax.y, healthDatas.heartRateMin.y));\r
-}\r
 \r
-uint16_t HeartModel::GetAveHeartRateCount(void)\r
-{\r
-    return aveCount;\r
-}\r
+    uint16_t HeartModel::GetAveHeartRateCount(void)\r
+    {\r
+        return aveCount;\r
+    }\r
 \r
-uint16_t HeartModel::GetHeartRateMax(void)\r
-{\r
-    return healthDatas.heartRateMax.y;\r
-}\r
+    uint16_t HeartModel::GetHeartRateMax(void)\r
+    {\r
+        return healthDatas.heartRateMax.y;\r
+    }\r
 \r
-uint16_t HeartModel::GetHeartRateMin(void)\r
-{\r
-    return healthDatas.heartRateMin.y;\r
-}\r
+    uint16_t HeartModel::GetHeartRateMin(void)\r
+    {\r
+        return healthDatas.heartRateMin.y;\r
+    }\r
 \r
-void HeartModel::SetHeartRatePerSec(uint32 sec)\r
-{\r
-    healthDatas.heartRatePerSec = sec;\r
-    if (HeartRateView::GetInstance() == nullptr) {\r
-        return;\r
+    void HeartModel::SetHeartRatePerSec(uint32 sec)\r
+    {\r
+        healthDatas.heartRatePerSec = sec;\r
+        if (HeartRateView::GetInstance() == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        HeartRateView::GetInstance()->RefreshHeartRatePerSec(healthDatas.heartRatePerSec);\r
     }\r
-    HeartRateView::GetInstance()->RefreshHeartRatePerSec(healthDatas.heartRatePerSec);\r
-}\r
 \r
-void HeartModel::SetAveHeartRateCount(uint16_t value)\r
-{\r
-    aveCount = value;\r
-}\r
+    void HeartModel::SetAveHeartRateCount(uint16_t value)\r
+    {\r
+        aveCount = value;\r
+    }\r
 \r
-void HeartModel::SetWearStatus(bool status)\r
-{\r
-    wearStatus = status;\r
-}\r
+    void HeartModel::SetWearStatus(bool status)\r
+    {\r
+        wearStatus = status;\r
+    }\r
 \r
-bool HeartModel::GetWearStatus(void)\r
-{\r
-    return wearStatus;\r
-}\r
+    bool HeartModel::GetWearStatus(void)\r
+    {\r
+        return wearStatus;\r
+    }\r
 \r
-void HeartModel::RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate)\r
-{\r
-    UNUSED(rest);\r
-    Point *rateData;\r
-    int len = GetAveHeartRateCount();\r
-    rateData = GetAveHeartRate();\r
+    void HeartModel::RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate)\r
+    {\r
+        UNUSED(rest);\r
+        Point *rateData;\r
+        int len = GetAveHeartRateCount();\r
+        rateData = GetAveHeartRate();\r
+\r
+        uint16_t currentViewId = NativeAbility::GetInstance().GetCurSliceId();\r
+        if (currentViewId == VIEW_MAIN && MainClockView::GetInstance() != nullptr)\r
+        {\r
+            MainClockView::GetInstance()->RefreshHeartRate(perSec);\r
+        }\r
+\r
+        if (IndoorWalkPreparedView::GetInstance() != nullptr)\r
+        {\r
+            IndoorWalkPreparedView::GetInstance()->RefreshHeartbeatData(perSec);\r
+        }\r
+        if (IndoorWalkPresenter::GetInstance() != nullptr)\r
+        {\r
+            IndoorWalkPresenter::GetInstance()->ModifiesHeartRate(perSec);\r
+        }\r
 \r
-    uint16_t currentViewId = NativeAbility::GetInstance().GetCurSliceId();\r
-    if (currentViewId == VIEW_MAIN && MainClockView::GetInstance() != nullptr) {\r
-        MainClockView::GetInstance()->RefreshHeartRate(perSec);\r
+        if (MainViewSample::GetInstance() != nullptr && HeartRateView::GetInstance() != nullptr)\r
+        {\r
+            if (MainViewSample::GetInstance()->GetHorCurrentPage() == HEART_RATE)\r
+            {\r
+                HeartRateView::GetInstance()->SetHeartRateData(rateData, sizeof(Point) * len);\r
+                HeartRateView::GetInstance()->RefreshElectrocardiogram();\r
+                HeartRateView::GetInstance()->RefreshHeartRatePerSec(perSec);\r
+                HeartRateView::GetInstance()->RefreshHeartRateMax(maxRate);\r
+                HeartRateView::GetInstance()->RefreshHeartRateMin(minRate);\r
+                HeartRateView::GetInstance()->RefreshRestHeartRate(rest);\r
+            }\r
+        }\r
+    }\r
+    bool HeartModel::GetHeartViewStatus(void)\r
+    {\r
+        return HeartView;\r
     }\r
 \r
-    if (IndoorWalkPreparedView::GetInstance() != nullptr) {\r
-        IndoorWalkPreparedView::GetInstance()->RefreshHeartbeatData(perSec);\r
+    bool HeartModel::GetHeartBandoffViewStatus(void)\r
+    {\r
+        return BandoffView;\r
     }\r
-    if (IndoorWalkPresenter::GetInstance() != nullptr) {\r
-        IndoorWalkPresenter::GetInstance()->ModifiesHeartRate(perSec);\r
+\r
+    bool HeartModel::GetHeartCheckViewStatus(void)\r
+    {\r
+        return CheckView;\r
     }\r
 \r
-    if (MainViewSample::GetInstance() != nullptr && HeartRateView::GetInstance() != nullptr) {\r
-        if (MainViewSample::GetInstance()->GetHorCurrentPage() == HEART_RATE) {\r
-            HeartRateView::GetInstance()->SetHeartRateData(rateData, sizeof(Point) * len);\r
-            HeartRateView::GetInstance()->RefreshElectrocardiogram();\r
-            HeartRateView::GetInstance()->RefreshHeartRatePerSec(perSec);\r
-            HeartRateView::GetInstance()->RefreshHeartRateMax(maxRate);\r
-            HeartRateView::GetInstance()->RefreshHeartRateMin(minRate);\r
+    void HeartModel::SetHeartBandoffViewStatus(bool bandoffViewStatus)\r
+    {\r
+        BandoffView = bandoffViewStatus;\r
+    }\r
+\r
+    void HeartModel::SetHeartViewStatus(bool HeartViewStatus)\r
+    {\r
+        HeartView = HeartViewStatus;\r
+    }\r
+\r
+    void HeartModel::SetHeartCheckViewStatus(bool checkViewStatus)\r
+    {\r
+        CheckView = checkViewStatus;\r
+    }\r
+\r
+    /* -------------------------------------------------------------------------- */\r
+    // 获取检测状态\r
+    bool HeartModel::GetCheckStatus()\r
+    {\r
+        return CheckStatus;\r
+    }\r
+    // 设置检测状态\r
+    void HeartModel::SetCheckStatus(bool checkstatus)\r
+    {\r
+        CheckStatus = checkstatus;\r
+    }\r
+    uint16_t HeartModel::GetHeartdata()\r
+    {\r
+        return Heart_;\r
+    }\r
+    uint16_t HeartModel::GetShowHeartdata()\r
+    {\r
+        return Show_Heart_;\r
+    }\r
+    void HeartModel::UpHeartdata(uint16_t heart)\r
+    {\r
+        // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpHeartdata Heart:%d->%d", Heart_, heart);\r
+        Show_Heart_ = heart;\r
+        // 筛选有效信息\r
+        if (Show_Heart_ != 0)\r
+        {\r
+            Heart_ = heart;\r
         }\r
     }\r
+    uint16_t HeartModel::GetCheckTime()\r
+    {\r
+        // 第一次进入,默认刚刚测试\r
+        if (initstatus)\r
+        {\r
+            TIME_ = HeartPresenter::GetInstance()->GetCurrentTime();\r
+            initstatus = false;\r
+        }\r
+        return TIME_;\r
+    }\r
+    void HeartModel::SetCheckTime(uint16_t time)\r
+    {\r
+        TIME_ = time;\r
+    }\r
+    /* -------------------------------------------------------------------------- */\r
 }\r
-}\r
-\r
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartPresenter.cpp
new file mode 100644 (file)
index 0000000..801111f
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: heartOxygen view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#include "HeartPresenter.h"
+#include "common/task_manager.h"
+#include "HeartView.h"
+#include "HeartModel.h"
+#include "HeartCheckView.h"
+#include "components/ui_label.h"
+#include "ChangeSliceListener.h"
+#include "broadcast_service.h"
+#include <fstream>
+#include "iostream"
+#include <sstream>
+#include <string>
+#include <cstdlib>
+#include <ctime>
+#include "wearable_log.h"
+#include "cmsis_os.h"
+#include "securec.h"
+#include "broadcast_service.h"
+#include "graphic_service.h"
+#include <chrono>
+#include <thread>
+#include "ppg_service.h"
+#include "displaybrightness/include/DisplayBrightnessModel.h"
+#include "power_display_service.h"
+#include "heartrate/include/HeartPresenter.h"
+#include "heartrate/include/HeartView.h"
+
+#define HEARTKEYABLE 0
+namespace OHOS
+{
+    static HeartPresenter *g_pMainView = nullptr;
+    HeartView *g_pheartview = HeartView::GetInstance();
+
+    static constexpr uint16_t PROGRESS_VALUE_MIN = 0;
+    static constexpr uint16_t PROGRESS_VALUE_MAX = 10;
+    /* -------------------------------------------------------------------------- */
+    // 获取当前的"时间分"
+    uint16_t HeartPresenter::GetCurrentTime()
+    {
+        time_t now = time(0);
+        struct tm *tblock = localtime(&now);
+
+        uint16_t current_time = tblock->tm_hour * 60 + tblock->tm_min;
+        return current_time;
+    }
+    // 获取时间差
+    std::string HeartPresenter::GetTDOA(uint16_t new_time, uint16_t old_time)
+    {
+        if (new_time == old_time)
+        {
+            return "刚刚";
+        }
+
+        int time_diff = new_time - old_time;
+        if (time_diff > 60)
+        {
+            int hours = time_diff / 60;
+            int minutes = time_diff % 60;
+            std::stringstream ss;
+            ss << hours << "小时";
+            if (minutes > 0)
+            {
+                ss << minutes << "分钟";
+            }
+            return ss.str() + "前";
+        }
+        else
+        {
+            std::stringstream ss;
+            ss << time_diff << "分钟前";
+            return ss.str();
+        }
+    }
+    /* -------------------------------------------------------------------------- */
+    HeartPresenter::HeartPresenter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartPresenter::new HeartPresenter");
+        g_pMainView = this;
+    }
+
+    HeartPresenter::~HeartPresenter()
+    {
+#if HEARTKEYABLE
+        if (keyActListenr != nullptr)
+        {
+            delete keyActListenr;
+            keyActListenr = nullptr;
+        }
+#endif
+        g_pMainView = nullptr;
+    }
+    HeartPresenter *HeartPresenter::GetInstance()
+    {
+        return g_pMainView;
+    }
+
+    void HeartPresenter::OnStart()
+    {
+        Presenter<HeartView>::OnStart();
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartPresenter::On Start ");
+#if HEARTKEYABLE
+        if (keyActListenr == nullptr)
+        {
+            keyActListenr = new KeyInputListener();
+            if (keyActListenr != nullptr)
+            {
+                RootView::GetInstance()->SetOnKeyActListener(keyActListenr);
+            }
+            else
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartPresenter::OnStart: new KeyInputListener fail");
+            }
+        }
+#endif
+    }
+
+    void HeartPresenter::OnPause(void) {}
+
+    void HeartPresenter::OnResume(void) {}
+
+    void HeartPresenter::OnStop(void) {}
+
+    bool HeartPresenter::CheckPointersValue()
+    {
+        if (HeartView::GetInstance() == nullptr)
+        {
+            return false;
+        }
+
+#if 0
+        if (HeartBandoffView::GetInstance() == nullptr)
+        {
+            return false;
+        }
+#endif
+        if (HeartModel::GetInstance() == nullptr)
+        {
+            return false;
+        }
+        return true;
+    }
+    bool HeartPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        return true;
+    }
+    bool HeartPresenter::OnDragEnd(UIView &view, const DragEvent &event)
+    {
+        if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT)
+        {
+            NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST);
+            return true;
+        }
+        return false;
+    }
+
+    bool HeartPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        UNUSED(view);
+        UNUSED(event);
+        // 主界面点击开始检测
+        if (strcmp(view.GetViewId(), "checkbegin") == 0)
+        {
+            //HeartView::GetInstance()->ChangeView(HEARTVIEW, HEARTBANDVIEW);
+            //HeartModel::GetInstance()->SetHeartBandoffViewStatus(true);
+            // HeartBandoffView::GetInstance()->GetImageAnimator()->Start();
+            return true;
+        }
+        // 从检测界面回到主界面
+        if (strcmp(view.GetViewId(), "checkstop") == 0)
+        {
+            HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTVIEW);
+            HeartModel::GetInstance()->SetHeartCheckViewStatus(false);
+            HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测
+            return true;
+        }
+        // 从检测失败界面回到检测界面
+        if (strcmp(view.GetViewId(), "ReCheck") == 0)
+        {
+            HeartView::GetInstance()->ChangeView(HEARTRESULT, HEARTCHECKVIEW);
+            HeartCheckView::GetInstance()->GetImageAnimator()->Start(); // 播放检测界面动画
+            HeartModel::GetInstance()->SetCheckStatus(true);            // 开始检测
+            return true;
+        }
+        // 从检测失败界面回到主界面
+        if (strcmp(view.GetViewId(), "StCheck") == 0)
+        {
+            HeartView::GetInstance()->ChangeView(HEARTRESULT, HEARTVIEW);
+            HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测
+            return true;
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartPresenter::OnClick");
+        return false;
+    }
+
+    // 增加按键事件
+    bool HeartPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
+    {
+#if HEARTKEYABLE
+        WEARABLE_LOGD("", "into the view is: %s\n", typeid(view).name());
+        uint16 keyID = event.GetKeyId();
+        WEARABLE_LOGD("", "into key! keyID %u\n", keyID);
+        // 如果是power键就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER))
+        {
+            // uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();
+            NativeAbility::GetInstance().ChangeSlice(VIEW_APPLIST);
+        }
+#endif
+        return true;
+    }
+    void HeartPresenter::ProgressNotify(void)
+    {
+        // 当检测状态为开始检测,开始检测
+        if (HeartModel::GetInstance()->GetCheckStatus() == true)
+        {
+            HeartCheckView::GetInstance()->UpHeartText(); // 更新
+            if (startheart == true)
+            {
+                // uint8_t md = PPG_SERVICE_CMD_TYPE_DO_Heart_TEST;
+                // send_ppg_cmd_msg(md);
+                startheart = false;
+            }
+        }
+
+        // 当检测状态为结束检测,结束检测
+        if (HeartModel::GetInstance()->GetCheckStatus() == false)
+        {
+            HeartView::GetInstance()->Upheartdata(); // 更新主界面
+            if (startheart == false)
+            {
+                // uint8_t md = PPG_SERVICE_CMD_TYPE_STOP_Heart_TEST;
+                // send_ppg_cmd_msg(md);
+                startheart = true;
+            }
+        }
+    }
+
+    void HeartPresenter::ReturnInterface()
+    {
+#if 0
+        // 佩戴动画播放完毕,前往检测界面
+        if (HeartModel::GetInstance()->GetHeartBandoffViewStatus() == true)
+        {
+            if (HeartBandoffView::GetInstance()->GetImageAnimator()->GetState() == false)
+            {
+                HeartView::GetInstance()->ChangeView(HEARTBANDVIEW, HEARTCHECKVIEW);
+                HeartModel::GetInstance()->SetHeartBandoffViewStatus(false);
+                // 设置检测界面状态
+                HeartModel::GetInstance()->SetHeartCheckViewStatus(true);
+                // 播放检测界面动画
+                HeartCheckView::GetInstance()->GetImageAnimator()->Start();
+                HeartModel::GetInstance()->SetCheckStatus(true); // 开始检测
+            }
+        }
+#endif
+        // 检测动画播放完毕
+        if (HeartModel::GetInstance()->GetHeartCheckViewStatus() == true)
+        {
+            if (HeartCheckView::GetInstance()->GetImageAnimator()->GetState() == false)
+            {
+                // 测试失败
+                if (HeartModel::GetInstance()->GetShowHeartdata() == 0)
+                {
+                    HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTRESULT);
+                }
+                // 测试成功
+                else
+                {
+                    HeartView::GetInstance()->ChangeView(HEARTCHECKVIEW, HEARTVIEW);
+                }
+                HeartModel::GetInstance()->SetCheckStatus(false); // 关闭检测
+                HeartModel::GetInstance()->SetHeartCheckViewStatus(false);
+            }
+            uint16_t time = GetCurrentTime();
+            HeartModel::GetInstance()->SetCheckTime(time); // 更新时间
+        }
+    }
+    void HeartPresenter::Notify(void)
+    {
+        ProgressNotify();
+        ReturnInterface();
+    }
+}
\ No newline at end of file
index 5ece7d2..d10236d 100644 (file)
@@ -13,8 +13,9 @@
 #include "ui_resource_image.h"\r
 #include "common/image_cache_manager.h"\r
 \r
-namespace OHOS {\r
-static HeartRateView *g_pHeartRateView = nullptr;\r
+namespace OHOS\r
+{\r
+    static HeartRateView *g_pHeartRateView = nullptr;\r
 \r
 // 背景坐标图形\r
 #define ACT_IMAGE_X 0                               // 图片坐标起点\r
@@ -101,698 +102,760 @@ static HeartRateView *g_pHeartRateView = nullptr;
 #define PERSEC_HEART_TEXT_WIDTH 75\r
 #define PERSEC_HEART_TEXT_HEIGHT (PERSEC_HEART_TEXT_FONT_SIZE + 5)\r
 \r
-// 心跳image\r
-static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
-    {PNG_A004_070_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_071_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_072_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_073_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_074_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_075_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_076_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_077_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_078_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_079_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-\r
-    {PNG_A004_080_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_081_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_082_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_083_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_084_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_085_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_086_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_087_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-    {PNG_A004_088_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT,\r
-        IMG_SRC_FILE_PATH},\r
-};\r
-\r
-HeartRateView::HeartRateView()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
-    dataNume = 0;\r
-    currIndex = 0;\r
-    serialIndex = 0;\r
-    maxRate = 0;\r
-    minRate = HEART_RATE_LIMIT_UPPER;\r
-    InitHeartRateData();\r
-    SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
-\r
-    g_pHeartRateView = this;\r
-}\r
-\r
-HeartRateView::~HeartRateView()\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
-    if (viewiInitStatus == true) {\r
-        int32_t i;\r
-        RemoveAll();\r
-        delete imageViewCoordinate;\r
-        imageViewCoordinate = nullptr;\r
-\r
-        chart->ClearDataSerial();\r
-        for (i = 0; i < HEART_AVE_NUM; i++) {\r
-            delete dataSerial[i];\r
-            dataSerial[i] = nullptr;\r
+    // 心跳image\r
+    static ImageAnimatorInfo g_heartBeatImageInfo[HEARTBEAT_IMAGE_NUM] = {\r
+        {PNG_A004_070_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_071_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_072_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_073_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_074_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_075_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_076_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_077_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_078_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_079_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+\r
+        {PNG_A004_080_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_081_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_082_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_083_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_084_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_085_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_086_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_087_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+        {PNG_A004_088_IMAGE_PATH, {HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y}, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT, IMG_SRC_FILE_PATH},\r
+    };\r
+\r
+    HeartRateView::HeartRateView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView");\r
+        dataNume = 0;\r
+        currIndex = 0;\r
+        serialIndex = 0;\r
+        maxRate = 0;\r
+        minRate = HEART_RATE_LIMIT_UPPER;\r
+        InitHeartRateData();\r
+        SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
+\r
+        g_pHeartRateView = this;\r
+    }\r
+\r
+    HeartRateView::~HeartRateView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::~HeartRateView");\r
+        if (viewiInitStatus == true)\r
+        {\r
+            int32_t i;\r
+            RemoveAll();\r
+            delete imageViewCoordinate;\r
+            imageViewCoordinate = nullptr;\r
+\r
+            chart->ClearDataSerial();\r
+            for (i = 0; i < HEART_AVE_NUM; i++)\r
+            {\r
+                delete dataSerial[i];\r
+                dataSerial[i] = nullptr;\r
+            }\r
+            delete chart;\r
+            chart = nullptr;\r
+            delete imageViewTop;\r
+            imageViewTop = nullptr;\r
+            delete imageViewBottom;\r
+            imageViewBottom = nullptr;\r
+            delete dataTopAndbottom;\r
+            dataTopAndbottom = nullptr;\r
+            imageAnimator->Stop();\r
+            delete imageAnimator;\r
+            imageAnimator = nullptr;\r
+            delete topRate;\r
+            topRate = nullptr;\r
+            delete bottomRate;\r
+            bottomRate = nullptr;\r
+            delete ratePerSec;\r
+            ratePerSec = nullptr;\r
+            delete ratePerSecText;\r
+            ratePerSecText = nullptr;\r
+            delete restRate;\r
+            restRate = nullptr;\r
+            delete restRateText1;\r
+            restRateText1 = nullptr;\r
+            delete restRateText2;\r
+            restRateText2 = nullptr;\r
         }\r
-        delete chart;\r
-        chart = nullptr;\r
-        delete imageViewTop;\r
-        imageViewTop = nullptr;\r
-        delete imageViewBottom;\r
-        imageViewBottom = nullptr;\r
-        delete dataTopAndbottom;\r
-        dataTopAndbottom = nullptr;\r
-        imageAnimator->Stop();\r
-        delete imageAnimator;\r
-        imageAnimator = nullptr;\r
-        delete topRate;\r
-        topRate = nullptr;\r
-        delete bottomRate;\r
-        bottomRate = nullptr;\r
-        delete ratePerSec;\r
-        ratePerSec = nullptr;\r
-        delete ratePerSecText;\r
-        ratePerSecText = nullptr;\r
-        delete restRate;\r
-        restRate = nullptr;\r
-        delete restRateText1;\r
-        restRateText1 = nullptr;\r
-        delete restRateText2;\r
-        restRateText2 = nullptr;\r
+        g_pHeartRateView = nullptr;\r
     }\r
-    g_pHeartRateView = nullptr;\r
-}\r
 \r
-HeartRateView *HeartRateView::GetInstance(void)\r
-{\r
-    return g_pHeartRateView;\r
-}\r
-\r
-int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
-{\r
-    int32_t ret;\r
-\r
-    heartRateData[0].x = INVALID_HEART_VALUE;\r
-    heartRateData[0].y = INVALID_HEART_VALUE;\r
-\r
-    ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
-    if (ret != 0) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+    HeartRateView *HeartRateView::GetInstance(void)\r
+    {\r
+        return g_pHeartRateView;\r
     }\r
-    return ret;\r
-}\r
 \r
-int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
-{\r
-    int ret;\r
+    int32_t HeartRateView::InitHeartRateData(void) // 初始化心率数据,将存放心率数据的有效字节设置为无效值\r
+    {\r
+        int32_t ret;\r
 \r
-    if (rateData == nullptr) {\r
-        return OHOS_FAILURE;\r
-    }\r
+        heartRateData[0].x = INVALID_HEART_VALUE;\r
+        heartRateData[0].y = INVALID_HEART_VALUE;\r
 \r
-    if (rateDataSize > sizeof(Point) * HEART_AVE_NUM) {\r
-        rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
-    }\r
-    InitHeartRateData();\r
-    ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
+        ret = memset_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM);\r
+        if (ret != 0)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+        }\r
+        return ret;\r
     }\r
 \r
-    return OHOS_SUCCESS;\r
-}\r
+    int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
+    {\r
+        int ret;\r
 \r
+        if (rateData == nullptr)\r
+        {\r
+            return OHOS_FAILURE;\r
+        }\r
 \r
-int32_t HeartRateView::HeartRateDataProc(void)\r
-{\r
-    int32_t i, ret;\r
-    Point datain[HEART_AVE_NUM];\r
+        if (rateDataSize > sizeof(Point) * HEART_AVE_NUM)\r
+        {\r
+            rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
+        }\r
+        InitHeartRateData();\r
+        ret = memcpy_s(heartRateData, sizeof(Point) * HEART_AVE_NUM, rateData, rateDataSize);\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s heartRateData fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
+        }\r
 \r
-    ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
+        return OHOS_SUCCESS;\r
     }\r
 \r
-    ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
-    if (ret != EOK) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
-        return OHOS_FAILURE;\r
-    }\r
+    int32_t HeartRateView::HeartRateDataProc(void)\r
+    {\r
+        int32_t i, ret;\r
+        Point datain[HEART_AVE_NUM];\r
 \r
-    dataNume = 0;\r
-    for (i = 0; i < HEART_AVE_NUM; i++) {\r
-        if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
-            datain[i].y <= HEART_RATE_LIMIT_UPPER) {\r
-            rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
-            rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
-            dataNume++;\r
+        ret = memcpy_s(datain, sizeof(Point) * HEART_AVE_NUM, heartRateData, sizeof(Point) * HEART_AVE_NUM);\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memcpy_s rateDataTmp fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
         }\r
-    }\r
-    return OHOS_SUCCESS;\r
-}\r
 \r
-void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
-{\r
-    label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
-    label->SetPosition(labelInfo.x, labelInfo.y);\r
-    label->Resize(labelInfo.width, labelInfo.height);\r
-    label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
-    Add(label);\r
-}\r
-\r
-void HeartRateView::HeartRateLabelDisplay(void)\r
-{\r
-    LabelInfo PerSecLabel = { PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
-                              PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT };\r
-    LabelInfo PerSecTextLabel = { PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
-                                  PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT };\r
-\r
-    LabelInfo topLabel = { HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT };\r
-    LabelInfo bottomLabel = { HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
-                              BOTTOM_TEXT_HEIGHT };\r
-\r
-    LabelInfo restRateLabel = { REST_HEART_RATE_FONT_SIZE, REST_HEART_RATE_X, REST_HEART_RATE_Y, REST_HEART_RATE_WIDTH,\r
-                                REST_HEART_RATE_HEIGHT };\r
-    LabelInfo restRateTextLabel1 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X1, REST_HEART_TEXT_Y1,\r
-                                     REST_HEART_TEXT_WIDTH1, REST_HEART_TEXT_HEIGHT1 };\r
-    LabelInfo restRateTextLabel2 = { REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X2, REST_HEART_TEXT_Y2,\r
-                                     REST_HEART_TEXT_WIDTH2, REST_HEART_TEXT_HEIGHT2 };\r
-\r
-    topRate = new UILabel();\r
-    bottomRate = new UILabel();\r
-    ratePerSec = new UILabel();\r
-    ratePerSecText = new UILabel();\r
-    restRate = new UILabel();\r
-    restRateText1 = new UILabel();\r
-    restRateText2 = new UILabel();\r
-\r
-    if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr ||\r
-        restRate == nullptr || restRateText1 == nullptr || restRateText2 == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
-    }\r
+        ret = memset_s(rateDataTmp, sizeof(Point) * HEART_AVE_NUM, INVALID_HEART_VALUE, sizeof(Point) * HEART_AVE_NUM); // 替换为无效值\r
+        if (ret != EOK)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateDataProc] memset_s rateDataTmp fail! ret = %d", ret);\r
+            return OHOS_FAILURE;\r
+        }\r
 \r
-    // 实时心率\r
-    SetLabel(ratePerSec, PerSecLabel);\r
-    SetLabel(ratePerSecText, PerSecTextLabel);\r
-    ratePerSec->SetText("--");\r
-    ratePerSecText->SetText("次/分");\r
-\r
-    // 最高最低心率\r
-    SetLabel(topRate, topLabel);\r
-    SetLabel(bottomRate, bottomLabel);\r
-    topRate->SetText("--");\r
-    bottomRate->SetText("--");\r
-\r
-    // 静息心率\r
-    SetLabel(restRate, restRateLabel);\r
-    SetLabel(restRateText1, restRateTextLabel1);\r
-    SetLabel(restRateText2, restRateTextLabel2);\r
-    restRateText1->SetText("静息");\r
-    restRate->SetText("--");\r
-    restRateText2->SetText("次/分");\r
-}\r
-\r
-void HeartRateView::HeartRateCoordinate(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
-    // 坐标图片\r
-    imageViewCoordinate = new UIImageView();\r
-    if (imageViewCoordinate == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
-        return;\r
-    }\r
-    imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
-    imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
-    imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
-    Add(imageViewCoordinate);\r
-\r
-    //  心电图坐标适配\r
-    chart = new UIChartPolyline();\r
-    if (chart == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
-        return;\r
-    }\r
-    chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
-    chart->SetWidth(COORDINATE_WIDTH);\r
-    chart->SetHeight(COORDINATE_HEIGHT);\r
-    chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
-    chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
-    chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
-\r
-    UIXAxis &xAxis = chart->GetXAxis();\r
-    UIYAxis &yAxis = chart->GetYAxis();\r
-    xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
-    yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
-    xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
-    yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
-    chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
-    Add(chart);\r
-}\r
-\r
-void HeartRateView::InsertTopAndBottomRateImage(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
-    imageViewTop = new UIImageView();\r
-    imageViewBottom = new UIImageView();\r
-    if (imageViewTop == nullptr || imageViewBottom == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
-        return;\r
-    }\r
-    imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
-    imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
-    imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
-    Add(imageViewTop);\r
-    imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
-    imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
-    imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
-    Add(imageViewBottom);\r
-}\r
-\r
-void HeartRateView::UpdataTopAndBottomRate(void)\r
-{\r
-    uint16_t bottom, top;\r
-    if (chart == nullptr) {\r
-        return;\r
-    }\r
-    if (dataTopAndbottom != nullptr) {\r
-        chart->DeleteDataSerial(dataTopAndbottom);\r
-        delete dataTopAndbottom;\r
-        dataTopAndbottom = nullptr;\r
-    }\r
-    dataTopAndbottom = new UIChartDataSerial();\r
-    if (dataTopAndbottom == nullptr) {\r
-        return;\r
-    }\r
-    if (dataNume != 1) {\r
-        dataTopAndbottom->SetMaxDataCount(dataNume);        // number of data points\r
-        dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
-    } else {\r
-        Point tmp[NUM_2];\r
-        tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
-        tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
-        dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
-        dataTopAndbottom->AddPoints(tmp, NUM_2);  // number of data points\r
-    }\r
-    dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
-    chart->AddDataSerial(dataTopAndbottom);\r
-    chart->Invalidate();\r
-\r
-    UIChartDataSerial::PointStyle pointStyle;\r
-    // 最低心跳\r
-    dataTopAndbottom->EnableBottomPoint(true);\r
-    pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
-    pointStyle.fillColor = Color::Gray();\r
-    pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
-    pointStyle.strokeColor = Color::Black();\r
-    dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
-    chart->Invalidate();\r
-\r
-    bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
-    // 最高心跳\r
-    dataTopAndbottom->EnableTopPoint(true);\r
-    pointStyle.fillColor = Color::Red();\r
-    pointStyle.radius = TOP_RADIUS; // Inner radius\r
-    pointStyle.strokeColor = Color::Black();\r
-    pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
-    dataTopAndbottom->SetTopPointStyle(pointStyle);\r
-    chart->Invalidate();\r
-\r
-    top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
-    if (top <= HEART_RATE_LIMIT_UPPER) {\r
-        maxRate = (maxRate >= top) ? maxRate : top;\r
-    }\r
-    if (bottom != 0) {\r
-        minRate = (minRate <= bottom) ? minRate : bottom;\r
-    }\r
-}\r
+        dataNume = 0;\r
+        for (i = 0; i < HEART_AVE_NUM; i++)\r
+        {\r
+            if (datain[i].x >= 0 && datain[i].x < HEART_AVE_NUM && datain[i].y > 0 &&\r
+                datain[i].y <= HEART_RATE_LIMIT_UPPER)\r
+            {\r
+                rateDataTmp[dataNume].x = datain[i].x + COORDINATE_VALUE;\r
+                rateDataTmp[dataNume].y = datain[i].y * ACT_IMAGE_COOR_PIXELS / ACT_IMAGE_COOR_VALUE;\r
+                dataNume++;\r
+            }\r
+        }\r
+        return OHOS_SUCCESS;\r
+    }\r
+\r
+    void HeartRateView::SetLabel(UILabel *label, LabelInfo labelInfo)\r
+    {\r
+        label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelInfo.fontSize);\r
+        label->SetPosition(labelInfo.x, labelInfo.y);\r
+        label->Resize(labelInfo.width, labelInfo.height);\r
+        label->SetStyle(STYLE_BACKGROUND_COLOR, OPA_TRANSPARENT);\r
+        Add(label);\r
+    }\r
+\r
+    void HeartRateView::HeartRateLabelDisplay(void)\r
+    {\r
+        LabelInfo PerSecLabel = {PERSEC_HEART_RATE_FONT_SIZE, PERSEC_HEART_RATE_X, PERSEC_HEART_RATE_Y,\r
+                                 PERSEC_HEART_RATE_WIDTH, PERSEC_HEART_RATE_HEIGHT};\r
+        LabelInfo PerSecTextLabel = {PERSEC_HEART_TEXT_FONT_SIZE, PERSEC_HEART_TEXT_X, PERSEC_HEART_TEXT_Y,\r
+                                     PERSEC_HEART_TEXT_WIDTH, PERSEC_HEART_TEXT_HEIGHT};\r
+\r
+        LabelInfo topLabel = {HEART_RATE_LIMIT_FONT_SIZE, TOP_TEXT_X, TOP_TEXT_Y, TOP_TEXT_WIDTH, TOP_TEXT_HEIGHT};\r
+        LabelInfo bottomLabel = {HEART_RATE_LIMIT_FONT_SIZE, BOTTOM_TEXT_X, BOTTOM_TEXT_Y, BOTTOM_TEXT_WIDTH,\r
+                                 BOTTOM_TEXT_HEIGHT};\r
+\r
+        LabelInfo restRateLabel = {REST_HEART_RATE_FONT_SIZE, REST_HEART_RATE_X, REST_HEART_RATE_Y, REST_HEART_RATE_WIDTH,\r
+                                   REST_HEART_RATE_HEIGHT};\r
+        LabelInfo restRateTextLabel1 = {REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X1, REST_HEART_TEXT_Y1,\r
+                                        REST_HEART_TEXT_WIDTH1, REST_HEART_TEXT_HEIGHT1};\r
+        LabelInfo restRateTextLabel2 = {REST_HEART_TEXT_FONT_SIZE, REST_HEART_TEXT_X2, REST_HEART_TEXT_Y2,\r
+                                        REST_HEART_TEXT_WIDTH2, REST_HEART_TEXT_HEIGHT2};\r
+\r
+        topRate = new UILabel();\r
+        bottomRate = new UILabel();\r
+        ratePerSec = new UILabel();\r
+        ratePerSecText = new UILabel();\r
+        restRate = new UILabel();\r
+        restRateText1 = new UILabel();\r
+        restRateText2 = new UILabel();\r
+\r
+        if (topRate == nullptr || bottomRate == nullptr || ratePerSec == nullptr || ratePerSecText == nullptr ||\r
+            restRate == nullptr || restRateText1 == nullptr || restRateText2 == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateLabelDisplay] new UILabel fail");\r
+        }\r
 \r
-void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
-{\r
-    Point tmp[NUM_2];\r
+        // 实时心率\r
+        SetLabel(ratePerSec, PerSecLabel);\r
+        SetLabel(ratePerSecText, PerSecTextLabel);\r
+        ratePerSec->SetText("--");\r
+        ratePerSecText->SetText("次/分");\r
 \r
-    if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM) {\r
-        return;\r
+        // 最高最低心率\r
+        SetLabel(topRate, topLabel);\r
+        SetLabel(bottomRate, bottomLabel);\r
+        topRate->SetText("--");\r
+        bottomRate->SetText("--");\r
+\r
+        // 静息心率\r
+        SetLabel(restRate, restRateLabel);\r
+        SetLabel(restRateText1, restRateTextLabel1);\r
+        SetLabel(restRateText2, restRateTextLabel2);\r
+        restRateText1->SetText("静息");\r
+        restRate->SetText("--");\r
+        restRateText2->SetText("次/分");\r
+    }\r
+\r
+    void HeartRateView::HeartRateCoordinate(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateCoordinate start");\r
+        // 坐标图片\r
+        imageViewCoordinate = new UIImageView();\r
+        if (imageViewCoordinate == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new imageViewCoordinate fail");\r
+            return;\r
+        }\r
+        imageViewCoordinate->SetPosition(ACT_IMAGE_X, ACT_IMAGE_Y);\r
+        imageViewCoordinate->SetWidth(ACT_IMAGE_COOR_WIDTH);\r
+        imageViewCoordinate->SetHeight(ACT_IMAGE_COOR_HEIGHT);\r
+        Add(imageViewCoordinate);\r
+\r
+        //  心电图坐标适配\r
+        chart = new UIChartPolyline();\r
+        if (chart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartRateCoordinate] new chart fail");\r
+            return;\r
+        }\r
+        chart->SetPosition(COORDINATE_POINT_X, COORDINATE_POINT_Y);\r
+        chart->SetWidth(COORDINATE_WIDTH);\r
+        chart->SetHeight(COORDINATE_HEIGHT);\r
+        chart->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+        chart->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
+        chart->SetStyle(STYLE_LINE_WIDTH, 1); // line width\r
+\r
+        UIXAxis &xAxis = chart->GetXAxis();\r
+        UIYAxis &yAxis = chart->GetYAxis();\r
+        xAxis.SetDataRange(0, COORDINATE_WIDTH); // 24小时对应的秒数\r
+        yAxis.SetDataRange(0, COORDINATE_HEIGHT);\r
+        xAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        yAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        chart->SetGradientOpacity(COORDINATE_GRAD_MIN_OPA, COORDINATE_GRAD_MAX_OPA);\r
+        Add(chart);\r
+    }\r
+\r
+    void HeartRateView::InsertTopAndBottomRateImage(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
+        imageViewTop = new UIImageView();\r
+        imageViewBottom = new UIImageView();\r
+        if (imageViewTop == nullptr || imageViewBottom == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InsertTopAndBottomRateImage] new imageViewTop or imageViewBottom fail");\r
+            return;\r
+        }\r
+        imageViewTop->SetPosition(TOP_IMAGE_X, TOP_IMAGE_Y);\r
+        imageViewTop->SetWidth(TOP_IMAGE_WIDTH);\r
+        imageViewTop->SetHeight(TOP_IMAGE_HEIGHT);\r
+        Add(imageViewTop);\r
+        imageViewBottom->SetPosition(BOTTOM_IMAGE_X, BOTTOM_IMAGE_Y);\r
+        imageViewBottom->SetWidth(BOTTOM_IMAGE_WIDTH);\r
+        imageViewBottom->SetHeight(BOTTOM_IMAGE_HEIGHT);\r
+        Add(imageViewBottom);\r
+    }\r
+\r
+    void HeartRateView::UpdataTopAndBottomRate(void)\r
+    {\r
+        uint16_t bottom, top;\r
+        if (chart == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (dataTopAndbottom != nullptr)\r
+        {\r
+            chart->DeleteDataSerial(dataTopAndbottom);\r
+            delete dataTopAndbottom;\r
+            dataTopAndbottom = nullptr;\r
+        }\r
+        dataTopAndbottom = new UIChartDataSerial();\r
+        if (dataTopAndbottom == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (dataNume != 1)\r
+        {\r
+            dataTopAndbottom->SetMaxDataCount(dataNume);        // number of data points\r
+            dataTopAndbottom->AddPoints(rateDataTmp, dataNume); // number of data points\r
+        }\r
+        else\r
+        {\r
+            Point tmp[NUM_2];\r
+            tmp[0].x = tmp[1].x = rateDataTmp[0].x;\r
+            tmp[0].y = tmp[1].y = rateDataTmp[0].y;\r
+            dataTopAndbottom->SetMaxDataCount(NUM_2); // number of data points\r
+            dataTopAndbottom->AddPoints(tmp, NUM_2);  // number of data points\r
+        }\r
+        dataTopAndbottom->SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0)); // 设置透明\r
+        chart->AddDataSerial(dataTopAndbottom);\r
+        chart->Invalidate();\r
+\r
+        UIChartDataSerial::PointStyle pointStyle;\r
+        // 最低心跳\r
+        dataTopAndbottom->EnableBottomPoint(true);\r
+        pointStyle.radius = BOTTOM_RADIUS; // Inner radius\r
+        pointStyle.fillColor = Color::Gray();\r
+        pointStyle.strokeWidth = BOTTOM_STROKE_WIDTH; // border width\r
+        pointStyle.strokeColor = Color::Black();\r
+        dataTopAndbottom->SetBottomPointStyle(pointStyle);\r
+        chart->Invalidate();\r
+\r
+        bottom = dataTopAndbottom->GetValleyData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+        // 最高心跳\r
+        dataTopAndbottom->EnableTopPoint(true);\r
+        pointStyle.fillColor = Color::Red();\r
+        pointStyle.radius = TOP_RADIUS; // Inner radius\r
+        pointStyle.strokeColor = Color::Black();\r
+        pointStyle.strokeWidth = TOP_STROKE_WIDTH; // border width\r
+        dataTopAndbottom->SetTopPointStyle(pointStyle);\r
+        chart->Invalidate();\r
+\r
+        top = dataTopAndbottom->GetPeakData() * ACT_IMAGE_COOR_VALUE / ACT_IMAGE_COOR_PIXELS;\r
+        if (top <= HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            maxRate = (maxRate >= top) ? maxRate : top;\r
+        }\r
+        if (bottom != 0)\r
+        {\r
+            minRate = (minRate <= bottom) ? minRate : bottom;\r
+        }\r
     }\r
 \r
-    tmp[0].x = tmp[1].x = rateData[index].x;\r
-    tmp[0].y = tmp[1].y = rateData[index].y;\r
+    void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
+    {\r
+        Point tmp[NUM_2];\r
+\r
+        if (rateData == nullptr || chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM)\r
+        {\r
+            return;\r
+        }\r
 \r
-    dataSerial[serialIndex] = new UIChartDataSerial();\r
-    if (dataSerial[serialIndex] == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
-        serialIndex++;\r
-        return;\r
-    }\r
+        tmp[0].x = tmp[1].x = rateData[index].x;\r
+        tmp[0].y = tmp[1].y = rateData[index].y;\r
 \r
-    dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
-    dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
-    dataSerial[serialIndex]->SetLineColor(Color::Red());\r
-    dataSerial[serialIndex]->SetFillColor(Color::Red());\r
-    dataSerial[serialIndex]->EnableGradient(true);\r
+        dataSerial[serialIndex] = new UIChartDataSerial();\r
+        if (dataSerial[serialIndex] == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramOnePoint] new dataSerial[%d] fail", serialIndex);\r
+            serialIndex++;\r
+            return;\r
+        }\r
 \r
-    chart->AddDataSerial(dataSerial[serialIndex]);\r
-    chart->Invalidate();\r
-    serialIndex++;\r
-}\r
+        dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
+        dataSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
+        dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+        dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+        dataSerial[serialIndex]->EnableGradient(true);\r
 \r
-void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
-{\r
-    uint16_t i = 0;\r
-    uint16_t j = 0;\r
-    uint16_t tmp = 1;\r
-    if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM) {\r
-        return;\r
+        chart->AddDataSerial(dataSerial[serialIndex]);\r
+        chart->Invalidate();\r
+        serialIndex++;\r
     }\r
 \r
-    while (i < rateDataNume) {\r
-        while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4)) { // 15分钟对应的秒数\r
-            tmp++;\r
-            j++;\r
+    void HeartRateView::ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume)\r
+    {\r
+        uint16_t i = 0;\r
+        uint16_t j = 0;\r
+        uint16_t tmp = 1;\r
+        if (rateData == nullptr || chart == nullptr || rateDataNume > HEART_AVE_NUM)\r
+        {\r
+            return;\r
         }\r
-        if (tmp == 1) {\r
-            ElectrocardiogramOnePoint(rateData, i);\r
-        } else {\r
-            if (serialIndex >= HEART_AVE_NUM) {\r
-                return;\r
+\r
+        while (i < rateDataNume)\r
+        {\r
+            while ((j + 1 < rateDataNume) && (rateData[j + 1].x - rateData[j].x <= NUM_4))\r
+            { // 15分钟对应的秒数\r
+                tmp++;\r
+                j++;\r
             }\r
-            if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0) {\r
-                dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
-                chart->Invalidate();\r
-            } else {\r
-                dataSerial[serialIndex] = new UIChartDataSerial();\r
-                if (dataSerial[serialIndex] == nullptr) {\r
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
-                    serialIndex++;\r
+            if (tmp == 1)\r
+            {\r
+                ElectrocardiogramOnePoint(rateData, i);\r
+            }\r
+            else\r
+            {\r
+                if (serialIndex >= HEART_AVE_NUM)\r
+                {\r
                     return;\r
                 }\r
-\r
-                dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
-                dataSerial[serialIndex]->AddPoints(rateData + i, tmp);   // number of data points\r
-                dataSerial[serialIndex]->SetLineColor(Color::Red());\r
-                dataSerial[serialIndex]->SetFillColor(Color::Red());\r
-                dataSerial[serialIndex]->EnableGradient(true);\r
-\r
-                chart->AddDataSerial(dataSerial[serialIndex]);\r
-                chart->Invalidate();\r
-                serialIndex++;\r
+                if (serialIndex > 0 && dataSerial[serialIndex - 1] != nullptr && i == 0)\r
+                {\r
+                    dataSerial[serialIndex - 1]->AddPoints(rateData + 1, tmp - 1); // number of data points\r
+                    chart->Invalidate();\r
+                }\r
+                else\r
+                {\r
+                    dataSerial[serialIndex] = new UIChartDataSerial();\r
+                    if (dataSerial[serialIndex] == nullptr)\r
+                    {\r
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[ElectrocardiogramMultiPoint] new dataSerial[%d] fail", serialIndex);\r
+                        serialIndex++;\r
+                        return;\r
+                    }\r
+\r
+                    dataSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // number of data points\r
+                    dataSerial[serialIndex]->AddPoints(rateData + i, tmp);   // number of data points\r
+                    dataSerial[serialIndex]->SetLineColor(Color::Red());\r
+                    dataSerial[serialIndex]->SetFillColor(Color::Red());\r
+                    dataSerial[serialIndex]->EnableGradient(true);\r
+\r
+                    chart->AddDataSerial(dataSerial[serialIndex]);\r
+                    chart->Invalidate();\r
+                    serialIndex++;\r
+                }\r
             }\r
+            i += tmp;\r
+            j = i;\r
+            tmp = 1;\r
         }\r
-        i += tmp;\r
-        j = i;\r
-        tmp = 1;\r
     }\r
-}\r
 \r
-void HeartRateView::HeartRateElectrocardiogram(void)\r
-{\r
-    if (dataNume == 0) {\r
-        return;\r
-    }\r
-    serialIndex = 0;\r
-    if (dataNume != 1) {\r
-        ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
-    } else {\r
-        ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
+    void HeartRateView::HeartRateElectrocardiogram(void)\r
+    {\r
+        if (dataNume == 0)\r
+        {\r
+            return;\r
+        }\r
+        serialIndex = 0;\r
+        if (dataNume != 1)\r
+        {\r
+            ElectrocardiogramMultiPoint(rateDataTmp, dataNume); // 多个点\r
+        }\r
+        else\r
+        {\r
+            ElectrocardiogramOnePoint(rateDataTmp, 0); // 一个点\r
+        }\r
+        currIndex = dataNume;\r
     }\r
-    currIndex = dataNume;\r
-}\r
 \r
-void HeartRateView::HeartbeatImageAnimator()\r
-{\r
-    imageAnimator = new UIImageAnimatorView();\r
-    if (imageAnimator == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
-        return;\r
-    }\r
-    imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
-    imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
-    imageAnimator->SetRepeat(true);\r
-    Add(imageAnimator);\r
-    imageAnimator->Start();\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimatorStart(void)\r
-{\r
-    if (imageAnimator != nullptr) {\r
+    void HeartRateView::HeartbeatImageAnimator()\r
+    {\r
+        imageAnimator = new UIImageAnimatorView();\r
+        if (imageAnimator == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[HeartbeatImageAnimator] new imageAnimator fail");\r
+            return;\r
+        }\r
+        imageAnimator->SetPosition(HEARTBEAT_IMAGE_X, HEARTBEAT_IMAGE_Y, HEARTBEAT_IMAGE_WIDTH, HEARTBEAT_IMAGE_HEIGHT);\r
+        imageAnimator->SetImageAnimatorSrc(g_heartBeatImageInfo, HEARTBEAT_IMAGE_NUM, HEARTBEAT_DELAY);\r
+        imageAnimator->SetRepeat(true);\r
+        Add(imageAnimator);\r
         imageAnimator->Start();\r
     }\r
-}\r
 \r
-void HeartRateView::HeartbeatImageAnimatorStop(void)\r
-{\r
-    if (imageAnimator != nullptr) {\r
-        imageAnimator->Stop();\r
+    void HeartRateView::HeartbeatImageAnimatorStart(void)\r
+    {\r
+        if (imageAnimator != nullptr)\r
+        {\r
+            imageAnimator->Start();\r
+        }\r
     }\r
-}\r
 \r
-bool HeartRateView::InitView(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitView");\r
-    HeartRateDataProc();\r
-    HeartRateLabelDisplay();\r
-    HeartbeatImageAnimator();\r
-    HeartRateCoordinate();\r
-    InsertTopAndBottomRateImage();\r
-    HeartRateElectrocardiogram();\r
-    UpdataTopAndBottomRate();\r
-    HeartbeatImageAnimatorStop();\r
-    InitRefreshInterface();\r
-    return true;\r
-}\r
-\r
-void HeartRateView::PreLoad(void)\r
-{\r
-    if (!viewiInitStatus) {\r
-        if (InitView()) {\r
-            viewiInitStatus = true;\r
+    void HeartRateView::HeartbeatImageAnimatorStop(void)\r
+    {\r
+        if (imageAnimator != nullptr)\r
+        {\r
+            imageAnimator->Stop();\r
         }\r
     }\r
 \r
-    if (!resLoadStatus) {\r
-        ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_HEARTRATE_TOP);\r
-        ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_HEARTRATE_BOTTOM);\r
-        ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_HEARTRATECOOR);\r
-        resLoadStatus = true;\r
+    bool HeartRateView::InitView(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitView");\r
+        HeartRateDataProc();\r
+        HeartRateLabelDisplay();\r
+        HeartbeatImageAnimator();\r
+        HeartRateCoordinate();\r
+        InsertTopAndBottomRateImage();\r
+        HeartRateElectrocardiogram();\r
+        UpdataTopAndBottomRate();\r
+        HeartbeatImageAnimatorStop();\r
+        InitRefreshInterface();\r
+        return true;\r
     }\r
-}\r
 \r
-void HeartRateView::UnLoad(void)\r
-{\r
-    if (resLoadStatus) {\r
-        ImageInfo* img = nullptr;\r
-        imageViewTop->SetSrc(img);\r
-        imageViewBottom->SetSrc(img);\r
-        imageViewCoordinate->SetSrc(img);\r
-        ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
-        resLoadStatus = false;\r
-    }\r
-}\r
+    void HeartRateView::PreLoad(void)\r
+    {\r
+        if (!viewiInitStatus)\r
+        {\r
+            if (InitView())\r
+            {\r
+                viewiInitStatus = true;\r
+            }\r
+        }\r
 \r
-void HeartRateView::InitRefreshInterface(void)\r
-{\r
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
-\r
-    Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
-    uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
-    SetHeartRateData(rateData, sizeof(Point) * len);\r
-    uint16_t maxRate = HeartModel::GetInstance()->GetHeartRateMax();\r
-    uint16_t minRate = HeartModel::GetInstance()->GetHeartRateMin();\r
-    RefreshElectrocardiogram();\r
-    if (maxRate > 0 && maxRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
-    }\r
-    if (minRate > 0 && minRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
+        if (!resLoadStatus)\r
+        {\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_HEARTRATE_TOP);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_HEARTRATE_BOTTOM);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_HEARTRATECOOR);\r
+            resLoadStatus = true;\r
+        }\r
     }\r
-}\r
 \r
-// 刷新心率曲线\r
-void HeartRateView::RefreshElectrocardiogram(void)\r
-{\r
-    int32_t ret;\r
-    uint16_t tmp, count;\r
-    Point *rate = nullptr;\r
-    Point modPoint;\r
-\r
-    ret = HeartRateDataProc();\r
-    if (ret != OHOS_SUCCESS) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
-        return;\r
+    void HeartRateView::UnLoad(void)\r
+    {\r
+        if (resLoadStatus)\r
+        {\r
+            ImageInfo *img = nullptr;\r
+            imageViewTop->SetSrc(img);\r
+            imageViewBottom->SetSrc(img);\r
+            imageViewCoordinate->SetSrc(img);\r
+            ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
+            resLoadStatus = false;\r
+        }\r
     }\r
-    rate = rateDataTmp;\r
 \r
-    if (chart == nullptr) {\r
-        return;\r
-    }\r
+    void HeartRateView::InitRefreshInterface(void)\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::HeartRateView::InitRefreshInterface");\r
 \r
-    if (currIndex >= HEART_AVE_NUM) {\r
-        currIndex = HEART_AVE_NUM;\r
-    }\r
-    if (dataNume > currIndex) {\r
-        tmp = dataNume - currIndex;\r
-        if (currIndex > 0) {\r
-            rate += (currIndex - 1);\r
-            tmp += 1;\r
+        Point *rateData = HeartModel::GetInstance()->GetAveHeartRate();\r
+        uint16_t len = HeartModel::GetInstance()->GetAveHeartRateCount();\r
+        SetHeartRateData(rateData, sizeof(Point) * len);\r
+        uint16_t maxRate = HeartModel::GetInstance()->GetHeartRateMax();\r
+        uint16_t minRate = HeartModel::GetInstance()->GetHeartRateMin();\r
+        RefreshElectrocardiogram();\r
+        if (maxRate > 0 && maxRate < HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
         }\r
-        ElectrocardiogramMultiPoint(rate, tmp);\r
-        currIndex = dataNume;\r
-    } else if (dataNume == currIndex) { // 当前点平均心率刷新\r
-        if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr) {\r
-            modPoint.x = rate[currIndex - 1].x;\r
-            modPoint.y = rate[currIndex - 1].y;\r
-\r
-            count = dataSerial[serialIndex - 1]->GetDataCount();\r
-            dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
-            chart->Invalidate();\r
+        if (minRate > 0 && minRate < HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
         }\r
-    } else {\r
-        return;\r
     }\r
-    UpdataTopAndBottomRate(); // 最高、最低心率\r
-}\r
 \r
-// 清空心率曲线\r
-void HeartRateView::ClearElectrocardiogram(void)\r
-{\r
-    int32_t i;\r
-    dataNume = 0;\r
-    currIndex = 0;\r
-    maxRate = 0;\r
-    minRate = HEART_RATE_LIMIT_UPPER;\r
-    InitHeartRateData();\r
-\r
-    if (chart == nullptr) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
-        return;\r
-    }\r
+    // 刷新心率曲线\r
+    void HeartRateView::RefreshElectrocardiogram(void)\r
+    {\r
+        int32_t ret;\r
+        uint16_t tmp, count;\r
+        Point *rate = nullptr;\r
+        Point modPoint;\r
 \r
-    if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr) {\r
-        ratePerSec->SetText("--");\r
-        topRate->SetText("--");\r
-        bottomRate->SetText("--");\r
-        restRate->SetText("--");\r
-    }\r
+        ret = HeartRateDataProc();\r
+        if (ret != OHOS_SUCCESS)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
+            return;\r
+        }\r
+        rate = rateDataTmp;\r
+\r
+        if (chart == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-    chart->DeleteDataSerial(dataTopAndbottom);\r
-    delete dataTopAndbottom;\r
-    dataTopAndbottom = nullptr;\r
-    for (i = 0; i < serialIndex; i++) {\r
-        delete dataSerial[i];\r
-        dataSerial[i] = nullptr;\r
+        if (currIndex >= HEART_AVE_NUM)\r
+        {\r
+            currIndex = HEART_AVE_NUM;\r
+        }\r
+        if (dataNume > currIndex)\r
+        {\r
+            tmp = dataNume - currIndex;\r
+            if (currIndex > 0)\r
+            {\r
+                rate += (currIndex - 1);\r
+                tmp += 1;\r
+            }\r
+            ElectrocardiogramMultiPoint(rate, tmp);\r
+            currIndex = dataNume;\r
+        }\r
+        else if (dataNume == currIndex)\r
+        { // 当前点平均心率刷新\r
+            if (serialIndex > 0 && serialIndex <= HEART_AVE_NUM && dataSerial[serialIndex - 1] != nullptr)\r
+            {\r
+                modPoint.x = rate[currIndex - 1].x;\r
+                modPoint.y = rate[currIndex - 1].y;\r
+\r
+                count = dataSerial[serialIndex - 1]->GetDataCount();\r
+                dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
+                chart->Invalidate();\r
+            }\r
+        }\r
+        else\r
+        {\r
+            return;\r
+        }\r
+        UpdataTopAndBottomRate(); // 最高、最低心率\r
     }\r
-    chart->ClearDataSerial();\r
 \r
-    serialIndex = 0;\r
-    chart->Invalidate();\r
-}\r
+    // 清空心率曲线\r
+    void HeartRateView::ClearElectrocardiogram(void)\r
+    {\r
+        int32_t i;\r
+        dataNume = 0;\r
+        currIndex = 0;\r
+        maxRate = 0;\r
+        minRate = HEART_RATE_LIMIT_UPPER;\r
+        InitHeartRateData();\r
+\r
+        if (chart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chart == nullptr");\r
+            return;\r
+        }\r
 \r
-// 刷新每秒上报的心率\r
-void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
-{\r
-    char heartRate[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+        if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr)\r
+        {\r
+            ratePerSec->SetText("--");\r
+            topRate->SetText("--");\r
+            bottomRate->SetText("--");\r
+            restRate->SetText("--");\r
+        }\r
 \r
-    if (ratePerSec == nullptr) {\r
-        return;\r
-    }\r
+        chart->DeleteDataSerial(dataTopAndbottom);\r
+        delete dataTopAndbottom;\r
+        dataTopAndbottom = nullptr;\r
+        for (i = 0; i < serialIndex; i++)\r
+        {\r
+            delete dataSerial[i];\r
+            dataSerial[i] = nullptr;\r
+        }\r
+        chart->ClearDataSerial();\r
 \r
-    if (value == 0) {\r
-        ratePerSec->SetText("--");\r
-        HeartbeatImageAnimatorStop();\r
-        return;\r
-    }\r
-    HeartbeatImageAnimatorStart();\r
-    if (value > NUM_99) {\r
-        ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
-    } else {\r
-        ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+        serialIndex = 0;\r
+        chart->Invalidate();\r
     }\r
-    if (ret > EOK) {\r
-        ratePerSec->SetText(heartRate);\r
-    }\r
-}\r
 \r
-// 刷新最大心率\r
-void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
-{\r
-    char top[NUM_4] = "--";\r
-    int32_t ret = 0;\r
-    maxRate = (maxRate >= max) ? maxRate : max;\r
-    if (topRate == nullptr) {\r
-        return;\r
-    }\r
-    if (maxRate <= HEART_RATE_LIMIT_LOWER) {\r
-        topRate->SetText("--");\r
-        return;\r
-    }\r
-    ret = sprintf_s(top, sizeof(top), "%u", maxRate);\r
-    if (ret > EOK) {\r
-        topRate->SetText(top);\r
-    }\r
-}\r
+    // 刷新每秒上报的心率\r
+    void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
+    {\r
+        char heartRate[NUM_4] = "--";\r
+        int32_t ret = 0;\r
 \r
-// 刷新最小心率\r
-void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
-{\r
-    char bottom[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+        if (ratePerSec == nullptr)\r
+        {\r
+            return;\r
+        }\r
 \r
-    minRate = (minRate <= min) ? minRate : min;\r
-    if (bottomRate == nullptr) {\r
-        return;\r
-    }\r
-    if (minRate >= HEART_RATE_LIMIT_UPPER) {\r
-        bottomRate->SetText("--");\r
-        return;\r
+        if (value == 0)\r
+        {\r
+            ratePerSec->SetText("--");\r
+            HeartbeatImageAnimatorStop();\r
+            return;\r
+        }\r
+        HeartbeatImageAnimatorStart();\r
+        if (value > NUM_99)\r
+        {\r
+            ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
+        }\r
+        else\r
+        {\r
+            ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+        }\r
+        if (ret > EOK)\r
+        {\r
+            ratePerSec->SetText(heartRate);\r
+        }\r
     }\r
-    ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
-    if (ret > EOK) {\r
-        bottomRate->SetText(bottom);\r
+\r
+    // 刷新最大心率\r
+    void HeartRateView::RefreshHeartRateMax(uint16_t max)\r
+    {\r
+        char top[NUM_4] = "--";\r
+        int32_t ret = 0;\r
+        maxRate = (maxRate >= max) ? maxRate : max;\r
+        if (topRate == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (maxRate <= HEART_RATE_LIMIT_LOWER)\r
+        {\r
+            topRate->SetText("--");\r
+            return;\r
+        }\r
+        ret = sprintf_s(top, sizeof(top), "%u", maxRate);\r
+        if (ret > EOK)\r
+        {\r
+            topRate->SetText(top);\r
+        }\r
     }\r
-}\r
 \r
-// 刷新静息心率\r
-void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
-{\r
-    char heartRate[NUM_4] = "--";\r
-    int32_t ret = 0;\r
+    // 刷新最小心率\r
+    void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
+    {\r
+        char bottom[NUM_4] = "--";\r
+        int32_t ret = 0;\r
 \r
-    if (restRate == nullptr) {\r
-        return;\r
+        minRate = (minRate <= min) ? minRate : min;\r
+        if (bottomRate == nullptr)\r
+        {\r
+            return;\r
+        }\r
+        if (minRate >= HEART_RATE_LIMIT_UPPER)\r
+        {\r
+            bottomRate->SetText("--");\r
+            return;\r
+        }\r
+        ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
+        if (ret > EOK)\r
+        {\r
+            bottomRate->SetText(bottom);\r
+        }\r
     }\r
 \r
-    if (value == 0 || value == (uint16_t)0xFFFF) { // 无效值\r
-        restRate->SetText("--");\r
-    } else {\r
-        if (value > NUM_99) {\r
-            ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
-        } else {\r
-            ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+    // 刷新静息心率\r
+    void HeartRateView::RefreshRestHeartRate(uint16_t value)\r
+    {\r
+        char heartRate[NUM_4] = "--";\r
+        int32_t ret = 0;\r
+\r
+        if (restRate == nullptr)\r
+        {\r
+            return;\r
         }\r
 \r
-        if (ret > EOK) {\r
-            restRate->SetText(heartRate);\r
+        if (value == 0 || value == (uint16_t)0xFFFF)\r
+        {\r
+            // 无效值\r
+            restRate->SetText("--");\r
+        }\r
+        else\r
+        {\r
+            if (value > NUM_99)\r
+            {\r
+                ret = sprintf_s(heartRate, sizeof(heartRate), "%u", value);\r
+            }\r
+            else\r
+            {\r
+                ret = sprintf_s(heartRate, sizeof(heartRate), " %u", value);\r
+            }\r
+\r
+            if (ret > EOK)\r
+            {\r
+                restRate->SetText(heartRate);\r
+            }\r
         }\r
     }\r
-}\r
 } // namespace OHOS\r
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartResultView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartResultView.cpp
new file mode 100644 (file)
index 0000000..20078ae
--- /dev/null
@@ -0,0 +1,249 @@
+
+
+#include "UiConfig.h"
+#include "wearable_log.h"
+#include "HeartResultView.h"
+#include "HeartModel.h"
+#include "ui_image_animator.h"
+#include "HeartResultView.h"
+namespace OHOS
+{
+    // 图片设置
+    static constexpr uint16_t IMAGE_SIZE = 80;
+    static constexpr uint16_t IMAGE_X = 193;
+    static constexpr uint16_t IMAGE_Y = 111;
+
+    // 按钮设置
+    static constexpr uint16_t BUTTON_LABEL_SIZE = 26;
+    static constexpr uint16_t BUTTON_WIDHT = 230;
+    static constexpr uint16_t BUTTON_HEIGHT = 80;
+    static constexpr uint16_t ST_BUTTON_X = 118;
+    static constexpr uint16_t ST_BUTTON_Y = 334;
+    static constexpr uint16_t RE_BUTTON_X = 118;
+    static constexpr uint16_t RE_BUTTON_Y = 434;
+
+    // 标签设置
+    static constexpr uint16_t LABLE_FONT_SIZE = 30;
+    static constexpr uint16_t TITLE_POSITION_X = 149;
+    static constexpr uint16_t TITLE_POSITION_Y = 52;
+    static constexpr uint16_t label1_POSITION_X = 58;
+    static constexpr uint16_t label1_POSITION_Y = 208;
+    static constexpr uint16_t label2_POSITION_X = 38;
+    static constexpr uint16_t label2_POSITION_Y = 243;
+    static constexpr uint16_t LABEL3_POSITION_X = 143;
+    static constexpr uint16_t LABEL3_POSITION_Y = 278;
+
+    static HeartResultView *g_pMainView = nullptr;
+    HeartResultView::HeartResultView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::HeartBandoffView");
+
+        g_pMainView = this;
+    }
+
+    HeartResultView *HeartResultView::GetInstance(void)
+    {
+        return g_pMainView;
+    }
+
+    HeartResultView::~HeartResultView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultView::~HeartResultView");
+        HeartResultScrollView->RemoveAll();
+        delete imageerror;
+        delete titlelabel;
+        delete label1;
+        delete label2;
+        delete label3;
+        delete ReButton;
+        delete StButton;
+        delete HeartResultScrollView;
+
+        titlelabel = nullptr;
+        label1 = nullptr;
+        label2 = nullptr;
+        label3 = nullptr;
+        HeartResultScrollView = nullptr;
+        ReButton = nullptr;
+        StButton = nullptr;
+        g_pMainView = this;
+    }
+    // 初始化标签
+    bool HeartResultView::InitLabel()
+    {
+        titlelabel = new UILabel();
+        if (titlelabel == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLabel fail");
+            return false;
+        }
+        titlelabel->SetPosition(149, 52); // widget's left position and top position
+        titlelabel->Resize(200, 60);      // widget's width and height
+        titlelabel->SetViewId("label1");  // Set style
+        titlelabel->SetStyle(STYLE_TEXT_FONT, 28);
+
+        // Set additional property
+        titlelabel->SetText("检测不到结果");
+        titlelabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        titlelabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        titlelabel->SetRollSpeed(0);
+        titlelabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 28);
+        /* -------------------------------------------------------------------------- */
+        label1 = new UILabel();
+        if (label1 == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLabel fail");
+            return false;
+        }
+        label1->SetPosition(53, 208); // widget's left position and top position
+        label1->Resize(200, 60);      // widget's width and height
+        label1->SetViewId("label4");  // Set style
+        label1->SetStyle(STYLE_TEXT_FONT, 30);
+
+        label1->SetText("请确认已带上手表,并保持");
+        label1->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        label1->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        label1->SetRollSpeed(0);
+        label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        /* -------------------------------------------------------------------------- */
+        label2 = new UILabel();
+        if (label2 == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLabel fail");
+            return false;
+        }
+        label2->SetPosition(38, 243); // widget's left position and top position
+        label2->Resize(200, 60);      // widget's width and height
+        label2->SetViewId("label5");  // Set style
+        label2->SetStyle(STYLE_TEXT_FONT, 30);
+        label2->SetText("静止,准备好后点击下方按钮");
+        label2->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        label2->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        label2->SetRollSpeed(0);
+        label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+
+        /* -------------------------------------------------------------------------- */
+        label3 = new UILabel();
+        if (label3 == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLabel fail");
+            return false;
+        }
+        label3->SetPosition(143, 278); // widget's left position and top position
+        label3->Resize(200, 60);       // widget's width and height
+        label3->SetViewId("label6");   // Set style
+        label3->SetStyle(STYLE_TEXT_FONT, 30);
+        label3->SetText("进行重新检测");
+        label3->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        label3->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        label3->SetRollSpeed(0);
+        label3->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+
+        return true;
+    }
+    // 初始化图片
+    bool HeartResultView::InitImageDisplay()
+    {
+        imageerror = new UIImageView();
+        if (imageerror == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitImageDisplay fail");
+            return false;
+        }
+        imageerror->SetPosition(193, 111); // widget's left position and top position
+        imageerror->Resize(100, 100);      // widget's width and height
+        imageerror->SetViewId("image1");   // Set style
+        char *image1imagesPath = "/user/res/Blood/Error.bin";
+        imageerror->SetSrc(image1imagesPath);
+        return true;
+    }
+    UIScrollView *HeartResultView::HeartResultViewInit()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartResultView::CreateUIViewHeartResultScrollView");
+        HeartResultScrollView = new UIScrollView();
+        if (HeartResultScrollView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartBandoffView::new HeartResultScrollView fail");
+            return nullptr;
+        }
+        HeartResultScrollView->SetPosition(0, 0);
+        HeartResultScrollView->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION);
+        HeartResultScrollView->SetScrollBlankSize(35);
+        HeartResultScrollView->SetReboundSize(50);
+        HeartResultScrollView->SetDirection(1);
+        // 增加拖拽监听
+        UIView::OnDragListener *draglistener = static_cast<UIView::OnDragListener *>(new HeartPresenter());
+        if (draglistener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::draglistener can not be nullptr!");
+            return nullptr;
+        }
+        HeartResultScrollView->SetOnDragListener(draglistener);
+        HeartResultScrollView->SetTouchable(true);
+        HeartResultScrollView->SetDraggable(true);
+        HeartResultScrollView->SetHorizontalScrollState(false); // 禁止横向滑动
+        /* -------------------------------------------------------------------------- */
+        if (InitImageDisplay() == false)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "nitImageDisplay fail");
+            return nullptr;
+        }
+        if (InitLabel() == false)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitLabel fail");
+            return nullptr;
+        }
+        /* -------------------------------------------------------------------------- */
+        ReButton = new UILabelButton();
+        if (ReButton == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UILabelButton fail");
+            return nullptr;
+        }
+        ReButton->SetPosition(118, 334);
+        ReButton->Resize(230, 80);
+        ReButton->SetText("重新检测");
+        ReButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xffFF8A36);
+        ReButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        ReButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED);
+        ReButton->SetViewId("ReCheck");
+        UIView::OnClickListener *clickLeft1Listener = (UIView::OnClickListener *)OHOS::HeartPresenter::GetInstance();
+        if (clickLeft1Listener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new clickLeft1Listener fail");
+            return nullptr;
+        }
+        ReButton->SetOnClickListener(clickLeft1Listener);
+        /* -------------------------------------------------------------------------- */
+        StButton = new UILabelButton();
+        if (StButton == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UILabelButton fail");
+            return nullptr;
+        }
+        StButton->SetPosition(118, 434); // widget's left position and top position
+        StButton->Resize(230, 80);       // widget's width and height
+        StButton->SetText("停止检测");
+        StButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+        StButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        StButton->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED);
+        StButton->SetViewId("StCheck");
+        UIView::OnClickListener *clickLeft2Listener = (UIView::OnClickListener *)OHOS::HeartPresenter::GetInstance();
+        if (clickLeft2Listener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new clickLeft2Listener fail");
+            return nullptr;
+        }
+        StButton->SetOnClickListener(clickLeft2Listener);
+        /* -------------------------------------------------------------------------- */
+        HeartResultScrollView->Add(imageerror);
+        HeartResultScrollView->Add(titlelabel);
+        HeartResultScrollView->Add(label1);
+        HeartResultScrollView->Add(label2);
+        HeartResultScrollView->Add(label3);
+        HeartResultScrollView->Add(ReButton);
+        HeartResultScrollView->Add(StButton);
+        /* -------------------------------------------------------------------------- */
+        return HeartResultScrollView;
+    }
+}
diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartView.cpp
new file mode 100644 (file)
index 0000000..8dcd0e5
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: heart view
+ * Author:
+ * Create: 2021-08-01
+ */
+
+#include "heartrate/include/HeartView.h"
+#include "heartrate/include/HeartPresenter.h"
+#include "HeartModel.h"
+#include "HeartPresenter.h"
+#include "displaybrightness/include/DisplayBrightnessModel.h"
+#include "power_display_service.h"
+
+namespace OHOS
+{
+    // 按钮设置
+    static constexpr uint16_t BUTTON_LABEL_SIZE = 30;
+    static constexpr uint16_t TESTBUTTON_X = 118;
+    static constexpr uint16_t TESTBUTTON_Y = 336;
+    static constexpr uint16_t BUTTON_WIDHT2 = 230;
+    static constexpr uint16_t BUTTON_HEIGHT2 = 80;
+
+    // 标签设置
+    static constexpr uint16_t PERCENT_X = 133;
+    static constexpr uint16_t PERCENT_Y = 103;
+    static constexpr uint16_t PERCENT_FONT_SIZE = 140;
+    static constexpr uint16_t TIMELABEL_X = 90;
+    static constexpr uint16_t TIMELABEL_Y = 260;
+    static constexpr uint16_t TIMELABEL_FONT_SIZE = 30;
+    static constexpr uint16_t TITLE_X = 151;
+    static constexpr uint16_t TITLE_Y = 55;
+    static constexpr uint16_t TITLE_FONT_SIZE = 28;
+
+    static constexpr uint16_t MATH_ZERO = 0;
+    static HeartView *g_pMainView = nullptr;
+
+    HeartView::HeartView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::HeartView");
+        g_pMainView = this;
+    }
+
+    HeartView::~HeartView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::~HeartView");
+        HeartScrollView[HEARTVIEW]->RemoveAll();
+        UIView::OnDragListener *draglistener = HeartScrollView[HEARTVIEW]->GetOnDragListener();
+        if (draglistener != nullptr)
+        {
+            delete draglistener;
+            draglistener = nullptr;
+        }
+        delete imageViewMain;
+        delete timeLabel;
+        delete titleLabel;
+        delete testButton;
+        delete percent;
+        delete heartcheck;
+
+        imageViewMain = nullptr;
+        titleLabel = nullptr;
+        timeLabel = nullptr;
+        percent = nullptr;
+        testButton = nullptr;
+        g_pMainView = nullptr;
+        heartcheck = nullptr;
+        delete HeartScrollView[HEARTVIEW];
+        HeartScrollView[HEARTVIEW] = nullptr;
+    }
+    HeartView *HeartView::GetInstance(void)
+    {
+        return g_pMainView;
+    }
+    void HeartView::Upheartdata()
+    {
+        // 更新血氧数据
+        uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata();
+        if (heart_ != 97) // 判断是否为默认数据
+        {
+            std::string heartStr = std::to_string(heart_);
+            percent->SetText(heartStr.c_str());
+        }
+        // 更新时间
+        uint16_t time = HeartPresenter::GetInstance()->GetCurrentTime();
+        uint16_t check_time = HeartModel::GetInstance()->GetCheckTime();
+        std::string TimeStr = HeartPresenter::GetInstance()->GetTDOA(time, check_time) + "检测";
+        timeLabel->SetText(TimeStr.c_str());
+    }
+
+    // 初始化标签
+    bool HeartView::InitLabel()
+    {
+        /* -------------------------------------------------------------------------- */
+        percent = new UILabel();
+        if (percent == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new percent fail");
+            return false;
+        }
+        percent->SetPosition(PERCENT_X, PERCENT_Y); // widget's left position and top position
+        percent->Resize(200, 200);                  // widget's width and height
+        percent->SetViewId("label2");               // Set style
+        percent->SetStyle(STYLE_TEXT_FONT, PERCENT_FONT_SIZE);
+        uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata();
+        std::string heartStr = std::to_string(heart_);
+        percent->SetText(heartStr.c_str());
+        percent->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+        percent->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        percent->SetRollSpeed(0);
+        percent->SetFont(DEFAULT_VECTOR_FONT_FILENAME, PERCENT_FONT_SIZE);
+        /* -------------------------------------------------------------------------- */
+        timeLabel = new UILabel();
+        if (timeLabel == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new timeLabel fail");
+            return false;
+        }
+        timeLabel->SetPosition(TIMELABEL_X, TIMELABEL_Y); // widget's left position and top position
+        timeLabel->Resize(280, 100);                      // widget's width and height
+        timeLabel->SetViewId("label1");                   // Set style
+        timeLabel->SetStyle(STYLE_TEXT_FONT, TIMELABEL_FONT_SIZE);
+        /* -------------------------------------------------------------------------- */
+        // 更新时间
+        uint16_t on_time = HeartPresenter::GetInstance()->GetCurrentTime();
+        uint16_t check_time = HeartModel::GetInstance()->GetCheckTime();
+        std::string TimeStr = HeartPresenter::GetInstance()->GetTDOA(on_time, check_time);
+        timeLabel->SetText(TimeStr.c_str());
+        /* -------------------------------------------------------------------------- */
+        timeLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+        timeLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        timeLabel->SetRollSpeed(0);
+        timeLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TIMELABEL_FONT_SIZE);
+        /* -------------------------------------------------------------------------- */
+        titleLabel = new UILabel();
+        if (titleLabel == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new titleLabel fail");
+            return false;
+        }
+        titleLabel->SetPosition(TITLE_X, TITLE_Y); // widget's left position and top position
+        titleLabel->Resize(200, 90);               // widget's width and height
+        titleLabel->SetViewId("label3");           // Set style
+        titleLabel->SetStyle(STYLE_TEXT_FONT, TITLE_FONT_SIZE);
+        titleLabel->SetText("心率检测结果");
+        titleLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+        titleLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        titleLabel->SetRollSpeed(0);
+        titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLE_FONT_SIZE);
+        /* -------------------------------------------------------------------------- */
+        return true;
+    }
+    // 创建标签按键
+    UILabelButton *HeartView::CreateAndSetUIButton(const char *title)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::CreateAndSetUIButton");
+        UILabelButton *btn = new UILabelButton();
+        if (btn == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new UILabelButton fail");
+            return nullptr;
+        }
+        btn->SetPosition(TESTBUTTON_X, TESTBUTTON_Y, BUTTON_WIDHT2, BUTTON_HEIGHT2);
+        btn->SetStyle(STYLE_BACKGROUND_COLOR, 0xffcd492c);
+        btn->SetText(title);
+        // btn->SetTextColor(Color::Red());
+        btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
+        btn->SetStyleForState(STYLE_BORDER_COLOR, 0xff0b1928, UIButton::PRESSED);
+        btn->SetAlign(TEXT_ALIGNMENT_CENTER);
+        btn->SetViewId("checkbegin");
+        UIView::OnClickListener *clickLeftListener = (UIView::OnClickListener *)OHOS::HeartPresenter::GetInstance();
+        if (clickLeftListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new clickLeftListener fail");
+            return nullptr;
+        }
+        btn->SetOnClickListener(clickLeftListener);
+        return btn;
+    }
+    // 初始化背景
+    bool HeartView::InitImageDisplay()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::InitImageDisplay");
+        imageViewMain = new UIImageView();
+        if (imageViewMain == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new UIImageView fail");
+            return false;
+        }
+        imageViewMain->SetPosition(MATH_ZERO, MATH_ZERO); // 30 :  offset
+        char *image1imagesPath = "/user/res/Blood/beijing.bin";
+        imageViewMain->SetSrc(image1imagesPath);
+        return true;
+    }
+    // 初始化界面
+    bool HeartView::InitHeartView()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::InitHeartView");
+        HeartScrollView[HEARTVIEW] = new UIScrollView();
+        if (HeartScrollView[HEARTVIEW] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::HeartScrollView new fail!");
+            return false;
+        }
+        HeartScrollView[HEARTVIEW]->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        HeartScrollView[HEARTVIEW]->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+        HeartScrollView[HEARTVIEW]->SetScrollBlankSize(35);
+        HeartScrollView[HEARTVIEW]->SetReboundSize(50);
+        HeartScrollView[HEARTVIEW]->SetDirection(1);
+        // 增加拖拽监听
+        UIView::OnDragListener *draglistener = static_cast<UIView::OnDragListener *>(new HeartPresenter());
+        if (draglistener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::draglistener can not be nullptr!");
+            return false;
+        }
+        HeartScrollView[HEARTVIEW]->SetOnDragListener(draglistener);
+        HeartScrollView[HEARTVIEW]->SetTouchable(true);
+        HeartScrollView[HEARTVIEW]->SetDraggable(true);
+        HeartScrollView[HEARTVIEW]->SetVerticalScrollState(false); // 禁止纵向滑动
+        /* -------------------------------------------------------------------------- */
+        if (InitImageDisplay() == false)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::InitImageDisplay() fail!");
+            return false;
+        }
+        if (InitLabel() == false)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::InitLabel() fail!");
+            return false;
+        }
+        testButton = CreateAndSetUIButton("检测");
+        if (testButton == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new Button fail");
+            return false;
+        }
+        /* -------------------------------------------------------------------------- */
+        return true;
+    }
+
+    // 1.跳转到心率界面
+    bool HeartView::ChangeHeartView(int16_t thisView)
+    {
+        if (HeartScrollView[thisView] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::ChangeHeartView");
+            RootView::GetInstance()->Add(HeartScrollView[thisView]);
+        }
+        return true;
+    }
+    // 3.跳转到检测界面
+    bool HeartView::ChangeCheckView(int16_t thisView)
+    {
+        if (HeartScrollView[thisView] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::ChangeCheckView");
+            heartcheck = new HeartCheckView();
+            if (heartcheck == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView:: new scrollView[%d] fail", thisView);
+                return false;
+            }
+            HeartScrollView[thisView] = heartcheck->HeartCheckViewInit();
+            RootView::GetInstance()->Add(HeartScrollView[thisView]);
+        }
+        return true;
+    }
+    // 4.跳转到检测失败界面
+    bool HeartView::ChangeResultView(int16_t thisView)
+    {
+        if (HeartScrollView[thisView] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::HeartResultView");
+            heartresult = new HeartResultView();
+            if (heartresult == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView:: new scrollView[%d] fail", thisView);
+                return false;
+            }
+            HeartScrollView[thisView] = heartresult->HeartResultViewInit();
+            RootView::GetInstance()->Add(HeartScrollView[thisView]);
+        }
+        return true;
+    }
+    UIScrollView *HeartView::GetHeartScrollView(int ViewId)
+    {
+        if (HeartScrollView[ViewId] == nullptr)
+        {
+            return nullptr;
+        }
+        return HeartScrollView[ViewId];
+    }
+    /* -------------------------------------------------------------------------- */
+    // 1.MainStopWatchViewMapper:结构体定义了一个将视图ID映射到特定成员函数指针的映射表。
+    struct HeartViewMapper
+    {
+        const int16_t viewId;
+        bool (HeartView::*func)(int16_t thisView);
+    };
+
+    // 2.ViewMapper[] 是一个静态的视图映射数组,将视图ID与MainStopWatchView类中的特定成员函数指针进行了绑定。
+    static const HeartViewMapper ViewMapper[] = {
+        {HEARTVIEW, &HeartView::ChangeHeartView},
+        {HEARTCHECKVIEW, &HeartView::ChangeCheckView},
+        {HEARTRESULT, &HeartView::ChangeResultView},
+    };
+
+    // 3.根据传入的interface参数执行相应视图ID关联的成员函数。
+    bool HeartView::ClickFunc(int16_t interface)
+    {
+        int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[HEARTVIEW]);
+        for (int i = 0; i < funcSize; i++)
+        {
+            if (interface == ViewMapper[i].viewId)
+            {
+                bool jug = (this->*(ViewMapper[i].func))(interface);
+                if (jug == false)
+                {
+                    return false;
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // 4.切换视图
+    void HeartView::ChangeView(int16_t hideView, int16_t showView)
+    {
+        if (hideView > MAX_HEARTVIEW)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView:: HeartViewId Overstep ones bounds");
+            return;
+        }
+        HeartScrollView[hideView]->SetVisible(false);
+        ClickFunc(showView);
+        HeartScrollView[showView]->SetVisible(true);
+        Draw();
+    }
+    /* -------------------------------------------------------------------------- */
+    bool HeartView::SetOnDragListener()
+    {
+        UIView::OnDragListener *dragListener = (UIView::OnDragListener *)OHOS::HeartPresenter::GetInstance();
+        if (dragListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::OnDragListener fail");
+            return false;
+        }
+        group->SetDraggable(true);
+        group->SetTouchable(true);
+        group->SetOnDragListener(dragListener);
+        return true;
+    }
+
+    void HeartView::OnStart()
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::OnStart");
+        display_time = DisplayBrightnessModel::GetInstance()->GetScreenDurationTime();
+        display_api->set_screen_auto_off_timeout(300 * 1000); // 设置常亮
+        View<HeartPresenter>::OnStart();
+        if (!InitHeartView())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::InitHeartView fail");
+        }
+    }
+
+    void HeartView::OnSetUpView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::OnSetUpView");
+        View<HeartPresenter>::OnSetUpView();
+        if (HeartScrollView[HEARTVIEW] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HEARTVIEW:: OnSetUpView  has nullptr");
+            return;
+        }
+        HeartScrollView[HEARTVIEW]->Add(imageViewMain);
+        HeartScrollView[HEARTVIEW]->Add(percent);
+        HeartScrollView[HEARTVIEW]->Add(timeLabel);
+        HeartScrollView[HEARTVIEW]->Add(titleLabel);
+        HeartScrollView[HEARTVIEW]->Add(testButton);
+        RootView::GetInstance()->Add(HeartScrollView[HEARTVIEW]);
+        Draw();
+    }
+
+    void HeartView::OnTearDownView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::OnTearDownView");
+        View<HeartPresenter>::OnTearDownView();
+        return;
+    }
+
+    void HeartView::OnStop()
+    {
+        display_api->set_screen_auto_off_timeout(display_time); // 恢复
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartView::OnStop");
+        View<HeartPresenter>::OnStop();
+        RootView::GetInstance()->RemoveAll();
+        return;
+    }
+}
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/APPLIST_CALLLOG.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/APPLIST_CALLLOG.bin
new file mode 100644 (file)
index 0000000..2666492
Binary files /dev/null and b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/APPLIST_CALLLOG.bin differ
index 0a4545f..f79c481 100644 (file)
@@ -167,6 +167,8 @@ void hx3695_msg_callback(uint8_t msg_type, uint8_t *msg_data, int32_t msg_datale
         case HX3695_MSG_TYPE_GRAYCARD_UPDATE:
             break;
         case HX3695_MSG_TYPE_WEARSTAT_UPDATE:
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_WEARSTATUS_UPDATE = %d", sensor_data.wearstatus);
+            //update_wearstatus_event_sendmsg_toUI(sensor_data.wearstatus);
             break;
         default:
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unknown sensor message type");