更新主界面心率卡片UI
authorCaisking <3449750381@qq.com>
Thu, 15 Aug 2024 08:47:47 +0000 (16:47 +0800)
committerCaisking <3449750381@qq.com>
Thu, 15 Aug 2024 08:47:47 +0000 (16:47 +0800)
code/sdk/application/wearable/fd230app/nativelauncher/include/ui_resource_image.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartRateView.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartRateView.cpp
code/sdk/application/wearable/nativeapp/nativeui/heartrate/src/HeartRateView.cpp

index bc18a57..778ca39 100644 (file)
@@ -13,9 +13,9 @@ namespace OHOS
     static const int DIR_MASK = 0xfff00000;
     static const int PNG_MASK = 0x000fffff;
 
-    static const int HEART_HEARTRATECOOR = 0x100001;
-    static const int HEART_HEARTRATE_BOTTOM = 0x100002;
-    static const int HEART_HEARTRATE_TOP = 0x100003;
+    static const int HEART_RATE_BOTTOM = 0x100001;
+    static const int HEART_RATE_COOR = 0x100002;
+    static const int HEART_RATE_TOP = 0x100003;
     /* -------------------------------------------------------------------------- */
     static const int PLAYER_BACKGROUND = 0x200001;            // 音乐背景
     static const int PLAYER_BLUETOOTH_COLOR = 0x200002;       // 蓝牙图标蓝色图片
index de7245c..23f1239 100644 (file)
@@ -17,7 +17,8 @@
 #include "components/ui_card_page.h"\r
 #include "HeartModel.h"\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
@@ -32,76 +33,86 @@ namespace OHOS {
 #define NUM_16 16\r
 #define NUM_99 99\r
 \r
-class HeartRateView : public UICardPage {\r
-public:\r
-    HeartRateView();\r
-    ~HeartRateView() override;\r
-    static HeartRateView *GetInstance(void);\r
+    class HeartRateView : public UICardPage\r
+    {\r
+    public:\r
+        HeartRateView();\r
+        ~HeartRateView() override;\r
+        static HeartRateView *GetInstance(void);\r
 \r
-    bool InitView(void);\r
-    void PreLoad(void) override;\r
-    void UnLoad(void) override;\r
-    int32_t SetHeartRateData(Point *rateData, uint32 rateDataSize); // 设置心率数据,用于画心率曲线\r
-    void RefreshElectrocardiogram(void); // 刷新心率曲线\r
-    void ClearElectrocardiogram(void); // 清空心率曲线\r
-    void RefreshHeartRatePerSec(uint16_t value); // 刷新每秒心率\r
-    void RefreshHeartRateMax(uint16_t max); // 刷新心率最大值\r
-    void RefreshHeartRateMin(uint16_t min); // 刷新心率最小值\r
-    void RefreshRestHeartRate(uint16_t value); // 刷新静息心率\r
-    void HeartbeatImageAnimatorStart(void); // 心形动画启动\r
-    void HeartbeatImageAnimatorStop(void); // 心形动画停止\r
-    void InitRefreshInterface(void);\r
+        bool InitView(void);\r
+        void PreLoad(void) override;\r
+        void UnLoad(void) override;\r
+        int32_t SetHeartRateData(Point *rateData, uint32 rateDataSize); // 设置心率数据,用于画心率曲线\r
+        void RefreshElectrocardiogram(void);                            // 刷新心率曲线\r
+        void ClearElectrocardiogram(void);                              // 清空心率曲线\r
+        void RefreshHeartRatePerSec(uint16_t value);                    // 刷新每秒心率\r
+        void RefreshHeartRateMax(uint16_t max);                         // 刷新心率最大值\r
+        void RefreshHeartRateMin(uint16_t min);                         // 刷新心率最小值\r
+        void RefreshRestHeartRate(uint16_t value);                      // 刷新静息心率\r
+        void HeartbeatImageAnimatorStart(void);                         // 心形动画启动\r
+        void HeartbeatImageAnimatorStop(void);                          // 心形动画停止\r
+        void InitRefreshInterface(void);\r
+        void InitChartTest(void);\r
+        void Init_data_Chart();\r
+        void Update_data_Chart(int serialIndex);\r
+        void UpdataChart();\r
 \r
-private:\r
-    typedef struct {\r
-        uint8_t fontSize;\r
-        int16 x;\r
-        int16 y;\r
-        int16 width;\r
-        int16 height;\r
-    } LabelInfo;\r
+    private:\r
+        typedef struct\r
+        {\r
+            uint8_t fontSize;\r
+            int16 x;\r
+            int16 y;\r
+            int16 width;\r
+            int16 height;\r
+        } LabelInfo;\r
 \r
-    int32_t InitHeartRateData(void);\r
-    void SetLabel(UILabel *label, LabelInfo labelInfo);\r
-    void HeartRateLabelDisplay(void);\r
-    void HeartRateCoordinate(void);\r
-    void HeartRateElectrocardiogram(void);\r
-    void InsertTopAndBottomRateImage(void);\r
-    void UpdataTopAndBottomRate(void);\r
-    void ElectrocardiogramOnePoint(Point *rateData, uint16_t index);\r
-    void ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume);\r
-    int32_t HeartRateDataProc(void);\r
-    void HeartbeatImageAnimator(void);\r
+        int32_t InitHeartRateData(void);\r
+        void SetLabel(UILabel *label, LabelInfo labelInfo);\r
+        void HeartRateLabelDisplay(void);\r
+        void HeartRateCoordinate(void);\r
+        void HeartRateElectrocardiogram(void);\r
+        void InsertTopAndBottomRateImage(void);\r
+        void UpdataTopAndBottomRate(void);\r
+        void ElectrocardiogramOnePoint(Point *rateData, uint16_t index);\r
+        void ElectrocardiogramMultiPoint(Point *rateData, uint16_t rateDataNume);\r
+        int32_t HeartRateDataProc(void);\r
+        void HeartbeatImageAnimator(void);\r
 \r
-private:\r
-    Point heartRateData[HEART_AVE_NUM];\r
-    Point rateDataTmp[HEART_AVE_NUM];\r
+    private:\r
+        Point heartRateData[HEART_AVE_NUM];\r
+        Point rateDataTmp[HEART_AVE_NUM];\r
 \r
-    void PreLoadHeartRateImageRes(void);\r
-    void UnLoadHeartRateImageRes(void);\r
-    bool viewiInitStatus{false};\r
-    bool resLoadStatus{false};\r
-    UIChartPolyline *chart{nullptr};\r
-    uint16_t dataNume; // 心率曲线记录数据总个数\r
-    uint16_t currIndex; // 当前已显示心率曲线心率个数\r
-    UIChartDataSerial *dataSerial[HEART_AVE_NUM]{nullptr};\r
-    UIChartDataSerial *dataTopAndbottom{nullptr};\r
-    UIImageView *imageViewTop{nullptr};\r
-    UIImageView *imageViewBottom{nullptr};\r
-    uint16_t serialIndex;\r
-    UIImageAnimatorView *imageAnimator{nullptr};\r
-    UIImageView *imageViewCoordinate{nullptr};\r
+        void PreLoadHeartRateImageRes(void);\r
+        void UnLoadHeartRateImageRes(void);\r
+        bool viewiInitStatus{false};\r
+        bool resLoadStatus{false};\r
+        UIChartPolyline *chart{nullptr};\r
+        uint16_t dataNume;  // 心率曲线记录数据总个数\r
+        uint16_t currIndex; // 当前已显示心率曲线心率个数\r
+        UIChartDataSerial *dataSerial[HEART_AVE_NUM]{nullptr};\r
+        UIChartDataSerial *dataTopAndbottom{nullptr};\r
+        UIImageView *imageViewTop{nullptr};\r
+        UIImageView *imageViewBottom{nullptr};\r
+        uint16_t serialIndex;\r
+        UIImageAnimatorView *imageAnimator{nullptr};\r
+        UIImageView *imageViewCoordinate{nullptr};\r
 \r
-    UILabel *topRate{nullptr};\r
-    UILabel *bottomRate{nullptr};\r
-    UILabel *ratePerSec{nullptr};\r
-    UILabel *ratePerSecText{nullptr};\r
-    UILabel *restRate{nullptr};\r
-    UILabel *restRateText1{nullptr};\r
-    UILabel *restRateText2{nullptr};\r
+        UILabel *topRate{nullptr};\r
+        UILabel *bottomRate{nullptr};\r
+        UILabel *ratePerSec{nullptr};\r
+        UILabel *ratePerSecText{nullptr};\r
+        UILabel *restRate{nullptr};\r
+        UILabel *restRateText1{nullptr};\r
+        UILabel *restRateText2{nullptr};\r
 \r
-    uint16_t maxRate;\r
-    uint16_t minRate;\r
-};\r
+        uint16_t maxRate;\r
+        uint16_t minRate;\r
+\r
+        Point heartdata[24];\r
+        UIChartDataSerial *heartSerial{nullptr};\r
+        UIChartPolyline *heartchart = nullptr;\r
+    };\r
 } // namespace OHOS\r
 #endif // HEART_RATE_VIEW_H\r
index a027ab0..083fdce 100644 (file)
 #include "ScreenModels.h"\r
 #include "ui_resource_image.h"\r
 #include "common/image_cache_manager.h"\r
-\r
+#include "heart_blood/health_service/health_service.h"\r
+#define HEART_DATA_TEST 0\r
 namespace OHOS\r
 {\r
     static HeartRateView *g_pHeartRateView = nullptr;\r
 \r
 // 背景坐标图形\r
-#define ACT_IMAGE_X 0                               // 图片坐标起点\r
-#define ACT_IMAGE_Y 115                             // 图片坐标起点\r
-#define ACT_IMAGE_COOR_X 45                         // 200刻度线到最左端的像素点\r
+#define ACT_IMAGE_X 38                              // 图片坐标起点\r
+#define ACT_IMAGE_Y 130                             // 图片坐标起点\r
+#define ACT_IMAGE_COOR_X 80                         // 200刻度线到最左端的像素点\r
 #define ACT_IMAGE_COOR_Y 145                        // 200刻度线到顶端的像素点\r
 #define ACT_IMAGE_COOR_PIXELS 160                   // 实际背景坐标0到200心率值的实际像素点\r
 #define ACT_IMAGE_COOR_VALUE HEART_RATE_LIMIT_UPPER // 图片刻度表示的心率范围\r
-#define ACT_IMAGE_COOR_WIDTH 454\r
-#define ACT_IMAGE_COOR_HEIGHT 220\r
+#define ACT_IMAGE_COOR_WIDTH 390\r
+#define ACT_IMAGE_COOR_HEIGHT 200\r
 \r
 // 心电图坐标适配\r
 #define COORDINATE_VALUE 5 // 余量\r
@@ -39,8 +40,8 @@ namespace OHOS
 // 心形心跳\r
 #define HEARTBEAT_IMAGE_WIDTH 92\r
 #define HEARTBEAT_IMAGE_HEIGHT 92\r
-#define HEARTBEAT_IMAGE_X 130\r
-#define HEARTBEAT_IMAGE_Y 25\r
+#define HEARTBEAT_IMAGE_X 105\r
+#define HEARTBEAT_IMAGE_Y 50\r
 #define HEARTBEAT_IMAGE_NUM 19\r
 #define HEARTBEAT_DELAY 50\r
 \r
@@ -90,10 +91,10 @@ namespace OHOS
 #define REST_HEART_TEXT_HEIGHT2 (REST_HEART_TEXT_FONT_SIZE + 5)\r
 \r
 // 每秒心率\r
-#define PERSEC_HEART_RATE_FONT_SIZE 45\r
-#define PERSEC_HEART_RATE_X 225\r
-#define PERSEC_HEART_RATE_Y 55\r
-#define PERSEC_HEART_RATE_WIDTH 90\r
+#define PERSEC_HEART_RATE_FONT_SIZE 60\r
+#define PERSEC_HEART_RATE_X 202\r
+#define PERSEC_HEART_RATE_Y 62\r
+#define PERSEC_HEART_RATE_WIDTH 102\r
 #define PERSEC_HEART_RATE_HEIGHT (PERSEC_HEART_RATE_FONT_SIZE + 5)\r
 \r
 #define PERSEC_HEART_TEXT_FONT_SIZE 30\r
@@ -157,6 +158,10 @@ namespace OHOS
                 delete dataSerial[i];\r
                 dataSerial[i] = nullptr;\r
             }\r
+            heartchart->ClearDataSerial();\r
+            delete heartSerial;\r
+            heartSerial = nullptr;\r
+            delete heartchart;\r
             delete chart;\r
             chart = nullptr;\r
             delete imageViewTop;\r
@@ -229,7 +234,27 @@ namespace OHOS
 \r
         return OHOS_SUCCESS;\r
     }\r
+#if 0\r
+    std::vector<Point> HeartRateView::simulateHeartRateData()\r
+    {\r
+        std::vector<Point> heartRateData;\r
+        const int HEART_RATE_MIN = 60;  // 心率下限\r
+        const int HEART_RATE_MAX = 100; // 心率上限\r
+\r
+        // 用于生成随机数的种子\r
+        std::srand(std::time(0));\r
+\r
+        for (int i = 0; i < 24; ++i)\r
+        { // 模拟24小时\r
+            Point dataPoint;\r
+            dataPoint.x = i;                                                                      // 小时数\r
+            dataPoint.y = HEART_RATE_MIN + (std::rand() % (HEART_RATE_MAX - HEART_RATE_MIN + 1)); // 随机生成心率值\r
+            heartRateData.push_back(dataPoint);\r
+        }\r
 \r
+        return heartRateData;\r
+    }\r
+#endif\r
     int32_t HeartRateView::HeartRateDataProc(void)\r
     {\r
         int32_t i, ret;\r
@@ -250,7 +275,7 @@ namespace OHOS
         }\r
 \r
         dataNume = 0;\r
-        for (i = 0; i < HEART_AVE_NUM; i++)\r
+        for (i = 0; i < HEART_AVE_NUM; i += 15) // 每跨过15个点代表一个小时\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
@@ -260,6 +285,7 @@ namespace OHOS
                 dataNume++;\r
             }\r
         }\r
+\r
         return OHOS_SUCCESS;\r
     }\r
 \r
@@ -308,6 +334,7 @@ namespace OHOS
         SetLabel(ratePerSec, PerSecLabel);\r
         SetLabel(ratePerSecText, PerSecTextLabel);\r
         ratePerSec->SetText("--");\r
+        ratePerSec->SetFont(GILROY_BOLD_FONT, PERSEC_HEART_RATE_FONT_SIZE);\r
         ratePerSecText->SetText("次/分");\r
 \r
         // 最高最低心率\r
@@ -361,9 +388,105 @@ namespace OHOS
         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
+        chart->SetVisible(false); // 设置不可见\r
         Add(chart);\r
     }\r
+    void HeartRateView::InitChartTest(void)\r
+    {\r
+        if (heartchart == nullptr)\r
+        {\r
+            heartchart = new UIChartPolyline();\r
+        }\r
+        heartchart->SetPosition(95, 178);\r
+        heartchart->Resize(320, 110);\r
+        heartchart->SetViewId("uiChart");\r
+        heartchart->SetStyle(STYLE_BACKGROUND_OPA, 0x00);\r
+\r
+        UIXAxis &heartXAxis = heartchart->GetXAxis();\r
+        UIYAxis &heartYAxis = heartchart->GetYAxis();\r
+        heartXAxis.SetMarkNum(1);\r
+        heartXAxis.SetDataRange(0, 24);\r
+        heartXAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        // heartXAxis.SetLineColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0xff));\r
+        heartYAxis.SetMarkNum(1);\r
+        heartYAxis.SetDataRange(0, 220);\r
+        heartYAxis.SetLineColor(Color::GetColorFromRGBA(0, 0, 0, 0));\r
+        // heartYAxis.SetLineColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0xff));\r
+\r
+        heartchart->SetGradientOpacity(0, 0);\r
+\r
+        Add(heartchart);\r
+    }\r
+    void HeartRateView::Init_data_Chart()\r
+    {\r
+        if (heartchart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Init_data_Chart new chart fail");\r
+            return;\r
+        }\r
+        heartSerial = new UIChartDataSerial();\r
+        heartSerial->SetMaxDataCount(24);\r
+#if HEART_DATA_TEST\r
+        Point temp[] = {\r
+            {0, 150}, {1, 250}, {2, 170}, {3, 0}, {4, 140}, {5, 190}, {6, 100}, {7, 40}, {8, 10}, {9, 100}, {10, 60}, {11, 20}, {12, 150}, {13, 250}, {14, 170}, {15, 140}, {16, 78}, {17, 80}, {18, 100}, {19, 20}, {20, 100}, {21, 100}, {22, 100}, {23, 100}};\r
+        std::copy(std::begin(temp), std::end(temp), heartdata);\r
+#else\r
+        for (int serialIndex = 0; serialIndex < 24; serialIndex++)\r
+        {\r
+            heartdata[serialIndex].x = serialIndex;\r
+            heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+        }\r
+#endif\r
+        heartSerial->AddPoints(heartdata, 24);\r
+        heartSerial->SetLineColor(Color::Red());\r
+        heartSerial->SetFillColor(Color::Red());\r
+        heartSerial->EnableGradient(true);\r
+\r
+        heartchart->AddDataSerial(heartSerial);\r
+        heartchart->Invalidate();\r
+    }\r
+    void HeartRateView::Update_data_Chart(int serialIndex)\r
+    {\r
+#if HEART_DATA_TEST\r
+        Point tmp[NUM_2];\r
+        if (chart == nullptr || index >= HEART_AVE_NUM || serialIndex >= HEART_AVE_NUM)\r
+        {\r
+            return;\r
+        }\r
+        heartSerial[serialIndex] = new UIChartDataSerial();\r
+        heartdata[serialIndex].x = serialIndex;\r
+        heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+\r
+        tmp[0].x = tmp[1].x = heartdata[serialIndex].x;\r
+        tmp[0].y = tmp[1].y = heartdata[serialIndex].y;\r
+\r
+        heartSerial[serialIndex]->SetMaxDataCount(HEART_AVE_NUM); // 设置最大显示的像素点\r
+        heartSerial[serialIndex]->AddPoints(tmp, NUM_2);\r
+        heartSerial[serialIndex]->SetLineColor(Color::Red());\r
+        heartSerial[serialIndex]->SetFillColor(Color::Red());\r
+        heartSerial[serialIndex]->EnableGradient(true);\r
+\r
+        heartchart->AddDataSerial(heartSerial[serialIndex]);\r
+        heartchart->Invalidate();\r
+#else\r
+        if (heartchart == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Update_data_Chart fail %d", serialIndex);\r
+            return;\r
+        }\r
+\r
+        heartdata[serialIndex].x = serialIndex;\r
+        heartdata[serialIndex].y = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);\r
+\r
+        heartSerial->AddPoints(heartdata, 24);\r
+        heartSerial->SetLineColor(Color::Red());\r
+        heartSerial->SetFillColor(Color::Red());\r
+        heartSerial->EnableGradient(true);\r
 \r
+        heartchart->AddDataSerial(heartSerial);\r
+        heartchart->Invalidate();\r
+#endif\r
+    }\r
     void HeartRateView::InsertTopAndBottomRateImage(void)\r
     {\r
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartRateView::InsertTopAndBottomRateImage start");\r
@@ -449,7 +572,6 @@ namespace OHOS
             minRate = (minRate <= bottom) ? minRate : bottom;\r
         }\r
     }\r
-\r
     void HeartRateView::ElectrocardiogramOnePoint(Point *rateData, uint16_t index)\r
     {\r
         Point tmp[NUM_2];\r
@@ -596,10 +718,12 @@ namespace OHOS
         HeartRateLabelDisplay();\r
         HeartbeatImageAnimator();\r
         HeartRateCoordinate();\r
+        InitChartTest();\r
+        Init_data_Chart();\r
         InsertTopAndBottomRateImage();\r
         HeartRateElectrocardiogram();\r
         UpdataTopAndBottomRate();\r
-        HeartbeatImageAnimatorStop();\r
+        // HeartbeatImageAnimatorStop(); 进入界面进行 动画播放\r
         InitRefreshInterface();\r
         return true;\r
     }\r
@@ -610,9 +734,10 @@ namespace OHOS
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoadHeartRateImageRes");\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
+            /*心率背景图*/\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_RATE_TOP);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_RATE_BOTTOM);\r
+            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_RATE_COOR);\r
             resLoadStatus = true;\r
         }\r
     }\r
@@ -628,9 +753,9 @@ namespace OHOS
             imageViewBottom->SetSrc(img);\r
             imageViewCoordinate->SetSrc(img);\r
             // ImageCacheManager::GetInstance().UnloadAllInMultiRes(HEART_IAMGES);\r
-            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_HEARTRATE_TOP, HEART_IAMGES);\r
-            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_HEARTRATE_BOTTOM, HEART_IAMGES);\r
-            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_HEARTRATECOOR, HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_TOP, HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_BOTTOM, HEART_IAMGES);\r
+            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_COOR, HEART_IAMGES);\r
             resLoadStatus = false;\r
         }\r
     }\r
@@ -885,6 +1010,7 @@ namespace OHOS
             }\r
         }\r
     }\r
+\r
 #if 0\r
 #ifdef __cplusplus\r
     extern "C"\r
index 8c96435..0d1144e 100755 (executable)
@@ -1,9 +1,10 @@
 /*\r
+\r
  * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.\r
  * Description: heartRate view\r
  * Author:\r
  * Create: 2021-07-26\r
- */\r
+   */\r
 \r
 #include <securec.h>\r
 #include "HeartRateView.h"\r
 #include "ScreenModels.h"\r
 #include "ui_resource_image.h"\r
 #include "common/image_cache_manager.h"\r
-\r
-namespace OHOS {\r
-static HeartRateView *g_pHeartRateView = nullptr;\r
+#define HEART_DATA_TEST 1\r
+namespace OHOS\r
+{\r
+    static HeartRateView *g_pHeartRateView = nullptr;\r
 \r
 // 背景坐标图形\r
-#define ACT_IMAGE_X 0                               // 图片坐标起点\r
-#define ACT_IMAGE_Y 115                             // 图片坐标起点\r
-#define ACT_IMAGE_COOR_X 45                         // 200刻度线到最左端的像素点\r
+#define ACT_IMAGE_X 38                              // 图片坐标起点\r
+#define ACT_IMAGE_Y 130                             // 图片坐标起点\r
+#define ACT_IMAGE_COOR_X 80                         // 200刻度线到最左端的像素点\r
 #define ACT_IMAGE_COOR_Y 145                        // 200刻度线到顶端的像素点\r
 #define ACT_IMAGE_COOR_PIXELS 160                   // 实际背景坐标0到200心率值的实际像素点\r
 #define ACT_IMAGE_COOR_VALUE HEART_RATE_LIMIT_UPPER // 图片刻度表示的心率范围\r
-#define ACT_IMAGE_COOR_WIDTH 454\r
-#define ACT_IMAGE_COOR_HEIGHT 220\r
+#define ACT_IMAGE_COOR_WIDTH 390\r
+#define ACT_IMAGE_COOR_HEIGHT 200\r
 \r
 // 心电图坐标适配\r
 #define COORDINATE_VALUE 5 // 余量\r
@@ -38,8 +40,8 @@ static HeartRateView *g_pHeartRateView = nullptr;
 // 心形心跳\r
 #define HEARTBEAT_IMAGE_WIDTH 92\r
 #define HEARTBEAT_IMAGE_HEIGHT 92\r
-#define HEARTBEAT_IMAGE_X 130\r
-#define HEARTBEAT_IMAGE_Y 25\r
+#define HEARTBEAT_IMAGE_X 105\r
+#define HEARTBEAT_IMAGE_Y 50\r
 #define HEARTBEAT_IMAGE_NUM 19\r
 #define HEARTBEAT_DELAY 50\r
 \r
@@ -89,10 +91,10 @@ static HeartRateView *g_pHeartRateView = nullptr;
 #define REST_HEART_TEXT_HEIGHT2 (REST_HEART_TEXT_FONT_SIZE + 5)\r
 \r
 // 每秒心率\r
-#define PERSEC_HEART_RATE_FONT_SIZE 45\r
-#define PERSEC_HEART_RATE_X 225\r
-#define PERSEC_HEART_RATE_Y 55\r
-#define PERSEC_HEART_RATE_WIDTH 90\r
+#define PERSEC_HEART_RATE_FONT_SIZE 60\r
+#define PERSEC_HEART_RATE_X 202\r
+#define PERSEC_HEART_RATE_Y 62\r
+#define PERSEC_HEART_RATE_WIDTH 102\r
 #define PERSEC_HEART_RATE_HEIGHT (PERSEC_HEART_RATE_FONT_SIZE + 5)\r
 \r
 #define PERSEC_HEART_TEXT_FONT_SIZE 30\r
@@ -101,686 +103,898 @@ 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) {\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
-        }\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
-    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
-    heartRateData[0].x = INVALID_HEART_VALUE;\r
-    heartRateData[0].y = INVALID_HEART_VALUE;\r
-\r
-    int32_t 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
-    }\r
-    return ret;\r
-}\r
-\r
-int32_t HeartRateView::SetHeartRateData(Point *rateData, uint32 rateDataSize)\r
-{\r
-    if (rateData == nullptr) {\r
-        return OHOS_FAILURE;\r
-    }\r
-\r
-    if (rateDataSize > sizeof(Point) * HEART_AVE_NUM) {\r
-        rateDataSize = sizeof(Point) * HEART_AVE_NUM;\r
-    }\r
-    InitHeartRateData();\r
-    int32_t 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
-    }\r
-    return OHOS_SUCCESS;\r
-}\r
-\r
-\r
-int32_t HeartRateView::HeartRateDataProc(void)\r
-{\r
-    Point datain[HEART_AVE_NUM];\r
-    int32_t 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
-    }\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
-\r
-    dataNume = 0;\r
-    for (int32_t 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
-        }\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
-\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
-    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
-    uint16_t 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
-    uint16_t 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
-\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
-        return;\r
-    }\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] = 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
-\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
-    chart->AddDataSerial(dataSerial[serialIndex]);\r
-    chart->Invalidate();\r
-    serialIndex++;\r
-}\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
-    }\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
-        }\r
-        if (tmp == 1) {\r
-            ElectrocardiogramOnePoint(rateData, i);\r
-        } else {\r
-            if (serialIndex >= HEART_AVE_NUM) {\r
-                return;\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
-                    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
-}\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
-    }\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
-        imageAnimator->Start();\r
-    }\r
-}\r
-\r
-void HeartRateView::HeartbeatImageAnimatorStop(void)\r
-{\r
-    if (imageAnimator != nullptr) {\r
-        imageAnimator->Stop();\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
-        }\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
-    }\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
-\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 maxHeartRate = HeartModel::GetInstance()->GetHeartRateMax();\r
-    uint16_t minHeartRate = HeartModel::GetInstance()->GetHeartRateMin();\r
-    RefreshElectrocardiogram();\r
-    if (maxHeartRate > 0 && maxHeartRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
-    }\r
-    if (minHeartRate > 0 && minHeartRate < HEART_RATE_LIMIT_UPPER) {\r
-        RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
-    }\r
-}\r
-\r
-// 刷新心率曲线\r
-void HeartRateView::RefreshElectrocardiogram(void)\r
-{\r
-    int32_t ret = HeartRateDataProc();\r
-    if (ret != OHOS_SUCCESS) {\r
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[RefreshElectrocardiogram()] fail");\r
-        return;\r
-    }\r
-    Point *rate = rateDataTmp;\r
-\r
-    if (chart == nullptr) {\r
-        return;\r
-    }\r
-\r
-    if (currIndex >= HEART_AVE_NUM) {\r
-        currIndex = HEART_AVE_NUM;\r
-    }\r
-    if (dataNume > currIndex) {\r
-        uint16_t tmp = dataNume - currIndex;\r
-        if (currIndex > 0) {\r
-            rate += (currIndex - 1);\r
-            tmp += 1;\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
-            Point modPoint;\r
-            modPoint.x = rate[currIndex - 1].x;\r
-            modPoint.y = rate[currIndex - 1].y;\r
-\r
-            uint16_t count = dataSerial[serialIndex - 1]->GetDataCount();\r
-            dataSerial[serialIndex - 1]->ModifyPoint(count - 1, modPoint);\r
-            chart->Invalidate();\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
-    if (ratePerSec != nullptr && topRate != nullptr && bottomRate != nullptr && restRate != nullptr) {\r
-        ratePerSec->SetText("--");\r
-        topRate->SetText("--");\r
-        bottomRate->SetText("--");\r
-        restRate->SetText("--");\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
-    }\r
-    chart->ClearDataSerial();\r
-\r
-    serialIndex = 0;\r
-    chart->Invalidate();\r
-}\r
-\r
-// 刷新每秒上报的心率\r
-void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
-{\r
-    char heartRate[NUM_4] = "--";\r
-    int32_t ret = 0;\r
-\r
-    if (ratePerSec == nullptr) {\r
-        return;\r
-    }\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
-    }\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
-// 刷新最小心率\r
-void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
-{\r
-    char bottom[NUM_4] = "--";\r
-    int32_t ret = 0;\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
-    }\r
-    ret = sprintf_s(bottom, sizeof(bottom), "%u", minRate);\r
-    if (ret > EOK) {\r
-        bottomRate->SetText(bottom);\r
-    }\r
-}\r
-\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
-        return;\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
-\r
-        if (ret > EOK) {\r
-            restRate->SetText(heartRate);\r
-        }\r
-    }\r
-}\r
-} // namespace OHOS\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
+​            UnLoadHeartRateImageRes();\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
+​        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
+​        {\r
+​            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::[InitHeartRateData] memset_s heartRateData fail! ret = %d", ret);\r
+​        }\r
+​        return ret;\r
+​    }\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
+​        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
+​        return OHOS_SUCCESS;\r
+​    }\r
+​    int32_t HeartRateView::HeartRateDataProc(void)\r
+​    {\r
+​        int32_t i, ret;\r
+​        Point datain[HEART_AVE_NUM];\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
+​        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
+​        dataNume = 0;\r
+​        for (i = 0; i < HEART_AVE_NUM; i += 15) // 每跨过15个点代表一个小时\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
+​    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
+​        // 实时心率\r
+​        SetLabel(ratePerSec, PerSecLabel);\r
+​        SetLabel(ratePerSecText, PerSecTextLabel);\r
+​        ratePerSec->SetText("--");\r
+​        ratePerSec->SetFont(GILROY_BOLD_FONT, PERSEC_HEART_RATE_FONT_SIZE);\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
+​        {\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
+\r
+\r
+​        // Point pointArray[5] = {{0, 200}, {1, 70}, {2, 80}, {3, 70}, {4, 43}};\r
+​        // dataSerial->AddPoints(pointArray, 5);\r
+​        // chart->AddDataSerial(dataSerial);\r
+\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
+​    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
+​        tmp[0].x = tmp[1].x = rateData[index].x;\r
+​        tmp[0].y = tmp[1].y = rateData[index].y;\r
+\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
+​        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
+​        chart->AddDataSerial(dataSerial[serialIndex]);\r
+​        chart->Invalidate();\r
+​        serialIndex++;\r
+​    }\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
+​        {\r
+​            return;\r
+​        }\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 (tmp == 1)\r
+​            {\r
+​                ElectrocardiogramOnePoint(rateData, i);\r
+​            }\r
+​            else\r
+​            {\r
+​                if (serialIndex >= HEART_AVE_NUM)\r
+​                {\r
+​                    return;\r
+​                }\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
+​    }\r
+\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
+\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
+​    void HeartRateView::HeartbeatImageAnimatorStart(void)\r
+​    {\r
+​        if (imageAnimator != nullptr)\r
+​        {\r
+​            imageAnimator->Start();\r
+​        }\r
+​    }\r
+\r
+​    void HeartRateView::HeartbeatImageAnimatorStop(void)\r
+​    {\r
+​        if (imageAnimator != nullptr)\r
+​        {\r
+​            imageAnimator->Stop();\r
+​        }\r
+​    }\r
+\r
+​    bool HeartRateView::InitView(void)\r
+​    {\r
+​        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "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::PreLoadHeartRateImageRes(void)\r
+​    {\r
+​        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoadHeartRateImageRes");\r
+​        if (!resLoadStatus)\r
+​        {\r
+​            /*心率背景图*/\r
+​            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewTop, HEART_RATE_TOP);\r
+​            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewBottom, HEART_RATE_BOTTOM);\r
+​            ScreenModels::GetInstance()->LoadAppImages(HEART_IAMGES, imageViewCoordinate, HEART_RATE_COOR);\r
+​            resLoadStatus = true;\r
+​        }\r
+​    }\r
+\r
+​    /*卸载心率图片资源*/\r
+​    void HeartRateView::UnLoadHeartRateImageRes(void)\r
+​    {\r
+​        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoadHeartRateImageRes");\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
+​            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_TOP, HEART_IAMGES);\r
+​            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_BOTTOM, HEART_IAMGES);\r
+​            ImageCacheManager::GetInstance().UnloadOneInMultiRes(HEART_RATE_COOR, HEART_IAMGES);\r
+​            resLoadStatus = false;\r
+​        }\r
+​    }\r
+\r
+​    void HeartRateView::PreLoad(void)\r
+​    {\r
+​        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::PreLoad");\r
+​        if (!viewiInitStatus)\r
+​        {\r
+​            if (InitView())\r
+​            {\r
+​                viewiInitStatus = true;\r
+​            }\r
+​        }\r
+​        PreLoadHeartRateImageRes();\r
+​    }\r
+\r
+​    void HeartRateView::UnLoad(void)\r
+​    {\r
+​        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView::UnLoad");\r
+​        UnLoadHeartRateImageRes();\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
+​        // 展示最大,最小,最近一次心率\r
+​        uint16_t maxRate = HeartModel::GetInstance()->GetHeartRateMax();\r
+​        uint16_t minRate = HeartModel::GetInstance()->GetHeartRateMin();\r
+​        uint16_t perRate = HeartModel::GetInstance()->GetHeartdata();\r
+​        RefreshElectrocardiogram();\r
+​        if (maxRate > 0 && maxRate < HEART_RATE_LIMIT_UPPER)\r
+​        {\r
+​            RefreshHeartRateMax(HeartModel::GetInstance()->GetHeartRateMax());\r
+​        }\r
+​        if (minRate > 0 && minRate < HEART_RATE_LIMIT_UPPER)\r
+​        {\r
+​            RefreshHeartRateMin(HeartModel::GetInstance()->GetHeartRateMin());\r
+​        }\r
+​        if (perRate > 0 && perRate < HEART_RATE_LIMIT_UPPER)\r
+​        {\r
+​            HeartModel::GetInstance()->SetHeartRatePerSec(perRate);\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
+​        {\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
+​        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
+\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
+​        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
+​        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
+​        serialIndex = 0;\r
+​        chart->Invalidate();\r
+​    }\r
+\r
+​    // 刷新每秒上报的心率\r
+​    void HeartRateView::RefreshHeartRatePerSec(uint16_t value)\r
+​    {\r
+​        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRateView %d", value);\r
+\r
+​        char heartRate[NUM_4] = "--";\r
+​        int32_t ret = 0;\r
+\r
+​        if (ratePerSec == nullptr)\r
+​        {\r
+​            return;\r
+​        }\r
+​        HeartbeatImageAnimatorStart(); // 界面创建实现动画跳动\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
+\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
+​    void HeartRateView::RefreshHeartRateMin(uint16_t min)\r
+​    {\r
+​        char bottom[NUM_4] = "--";\r
+​        int32_t ret = 0;\r
+\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
+​    // 刷新静息心率\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 (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
+#if 0\r
+#ifdef __cplusplus\r
+​    extern "C"\r
+​    {\r
+#endif\r
+​        /* 定时器回调函数 */\r
+​        void HeartTimerCallback()\r
+​        {\r
+​            g_motionTimes++;\r
+​            HeartCardPresenter *gHeartCardPresenter = HeartPresenter::GetInstance();\r
+​            if (gHeartCardPresenter == nullptr)\r
+​            {\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartTimerCallback::gHeartCardPresenter new fail");\r
+​                return;\r
+​            }\r
+​            // gHeartCardPresenter->ModifiesTime();\r
+​            // PRINT("HeartTimerCallback\r\n");\r
+​        }\r
+\r
+​        /* 开启定时器 */\r
+​        void InitTimer(void)\r
+​        {\r
+​            if (g_startCounting != NULL)\r
+​            {\r
+​                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer already exists!!");\r
+​                return;\r
+​            }\r
+​            g_startCounting = osTimerNew((osTimerFunc_t)HeartTimerCallback, osTimerPeriodic, NULL, NULL);\r
+​            if (g_startCounting == NULL)\r
+​            {\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerNew failed!!");\r
+​                return;\r
+​            }\r
+​            int tick = osMs2Tick(MS_ONE_SECONDS);\r
+​            osStatus_t retTimer = osTimerStart(g_startCounting, tick);\r
+​            if (retTimer != osOK)\r
+​            {\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::HeartTimer osTimerStart failed, ret = %lx!!", retTimer);\r
+​                if (g_startCounting != NULL)\r
+​                {\r
+​                    retTimer = osTimerDelete(g_startCounting);\r
+​                    if (retTimer != osOK)\r
+​                    {\r
+​                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartModel::osTimerDelete failed, ret = %lx!!", retTimer);\r
+​                        return;\r
+​                    }\r
+​                    g_startCounting = NULL;\r
+​                }\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "InitTimer!");\r
+​                return;\r
+​            }\r
+​        }\r
+​        /* 关闭定时器 */\r
+​        void DisableTimer(void)\r
+​        {\r
+​            if (g_startCounting != NULL)\r
+​            {\r
+​                osStatus_t ret = osTimerDelete(g_startCounting);\r
+​                if (ret != osOK)\r
+​                {\r
+​                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret);\r
+​                    return;\r
+​                }\r
+​                g_startCounting = NULL;\r
+​                PRINT("g_motionTimes:%d\r\n", sportdata->duration);\r
+​                g_motionTimes = 0;\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "DisableTimer!");\r
+​            }\r
+​        }\r
+​        /* 暂停定时器 */\r
+​        void PauseTimer(void)\r
+​        {\r
+​            // 检查定时器是否存在\r
+​            if (g_startCounting != NULL)\r
+​            {\r
+​                // 暂停定时器,但不删除它\r
+​                osStatus_t ret = osTimerStop(g_startCounting);\r
+​                if (ret != osOK)\r
+​                {\r
+​                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StopWatch_PauseTimer osTimerStop failed, ret = %lx!!", ret);\r
+​                }\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "PauseTimer!");\r
+​            }\r
+​        }\r
+\r
+​        /*恢复定时器*/\r
+​        void ResumeTimer(void)\r
+​        {\r
+​            // 检查定时器是否存在\r
+​            if (g_startCounting != NULL)\r
+​            {\r
+​                int tick = osMs2Tick(MS_ONE_SECONDS);\r
+​                // 恢复定时器\r
+​                osStatus_t ret = osTimerStart(g_startCounting, tick);\r
+​                if (ret != osOK)\r
+​                {\r
+​                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer osTimerStart failed, ret = %lx!!", ret);\r
+​                }\r
+​                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ResumeTimer!");\r
+​            }\r
+​        }\r
+\r
+#ifdef __cplusplus\r
+    }\r
+#endif\r
+#endif\r
+} // namespace OHOS
\ No newline at end of file