Merge #260 into sdk602patch0521 from refs/changes/260/head
author罗正 <1732036298@qq.com>
Wed, 12 Jun 2024 03:40:10 +0000 (03:40 +0000)
committersnickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Wed, 12 Jun 2024 03:40:10 +0000 (03:40 +0000)
Code review from 罗正

* refs/changes/260/head: (5 commits squashed)

  - 呼吸训练添加训练完成视图

  - Merge branch &#39;sdk602patch0521&#39; of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk602patch0521

  - 呼吸训练优化,差获取心率值接口,界面也还需要部分优化

  - Merge branch &#39;sdk602patch0521&#39; of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk602patch0521

  - 呼吸训练优化修改

Signed-off-by: 罗正 <1732036298@qq.com>
Reviewed-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Merged-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/260
code/sdk/application/wearable/fd230app/CMakeLists.txt
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingCompletedView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingModel.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingCompletedView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCGroupList.bin [new file with mode: 0644]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCVector.bin [new file with mode: 0644]
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RespiratoryTraining.bin

index 6f4c9e5..ed13545 100644 (file)
@@ -372,6 +372,8 @@ set(SOURCES
     #呼吸训练
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingPresenter.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingCompletedView.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp
 
     #声音与震动
     ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/soundandvibration/src/SoundAndVibrationPresenter.cpp 
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingCompletedView.h b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingCompletedView.h
new file mode 100644 (file)
index 0000000..688380b
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-08 18:24:24
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-11 14:41:30
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingCompletedCompletedView.h
+ */
+
+#ifndef RESPIRATORY_TRAINING_COMPLETED_VIEW_H
+#define RESPIRATORY_TRAINING_COMPLETED_VIEW_H
+
+#include "BaseView.h"
+#include "View.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_label_button_ext.h"
+#include "components/ui_image_view.h"
+
+namespace OHOS
+{
+    static constexpr int MAX_NUM = 3;
+    static constexpr const char *RTCLABELBUTTON = "RTCLabelButton";
+    static constexpr const char *RTCVectorImagePath = "/user/res/RespiratoryTraining/RTCVector.bin";
+    static constexpr const char *RTCGroupListImagePath = "/user/res/RespiratoryTraining/RTCGroupList.bin";
+    class RespiratoryTrainingCompletedView
+    {
+    public:
+        struct LabelConfig
+        {
+            int16_t left;
+            int16_t top;
+            int16_t width;
+            int16_t height;
+            int16_t fontSize;  // 字体大小
+            int16_t lineHeigh; // 行高
+            const char *text;
+            int16_t textId;
+            uint8_t lineBreakMode; // 断行模式。
+        };
+
+        struct ImageConfig
+        {
+            int16_t x;
+            int16_t y;
+            int16_t w;
+            int16_t h;
+        };
+
+        RespiratoryTrainingCompletedView();
+        ~RespiratoryTrainingCompletedView();
+        static RespiratoryTrainingCompletedView *GetInstance(void);
+        UIScrollView *RespiratoryTrainingCompletedViewInit(void);
+
+    private:
+        void ClearAll(void);
+        bool CreateRespiratoryTrainingCompletedScrollView();
+        bool CreateRespiratoryTrainingCompletedLabelView();
+        bool CreateRespiratoryTrainingCompletedImageView();
+        bool CreateRespiratoryTrainingCompletedLabelButtonView();
+        UILabelExt *LabelExtViewInit(const LabelConfig &labelconfig);
+        UILabel *LabelViewInit(const LabelConfig &labelconfig);
+        UIImageView *ImageViewInit(ImageConfig &imageconfig);
+        UIScrollView *ScrollView{nullptr};
+        UILabelExt *Title{nullptr};
+        UILabelExt *RespiratoryTrainingLabel{nullptr};
+        UIImageView *RespiratoryTrainingImage{nullptr};
+        UILabelExt *RTCStaticLabelView[MAX_NUM]{nullptr};
+        UILabel *RTCDynamicLabelView[MAX_NUM]{nullptr};
+        UIImageView *RTCImageView[MAX_NUM]{nullptr};
+        UILabelButtonExt *RTCLabelButton{nullptr};
+    };
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingModel.h b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingModel.h
new file mode 100644 (file)
index 0000000..bb26359
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-11 16:26:13
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 10:35:46
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingModel.h
+ */
+#ifndef RESPIRATORY_TRAINING_MODEL_H
+#define RESPIRATORY_TRAINING_MODEL_H
+
+#include <cstdint>
+#include <iostream>
+#include "string"
+namespace OHOS
+{
+    class RespiratoryTrainingModel
+    {
+    public:
+        static RespiratoryTrainingModel &GetInstance(void);
+        void AddRespiratoryTrainingTimes(void);
+        std::string GetRespiratoryTrainingTotalTime(void) ;
+        std::string GetHeartRateValue(void) ;
+        void ResumeStatus();
+        
+        void RT_StartTimer(uint32_t interval);
+        void RT_StopTimer(void);
+
+    private:
+        RespiratoryTrainingModel();
+        ~RespiratoryTrainingModel();
+        RespiratoryTrainingModel(const RespiratoryTrainingModel &) = delete;
+        RespiratoryTrainingModel &operator=(const RespiratoryTrainingModel &) = delete;
+
+        int RespiratoryTrainingTimes{0}; // 呼吸训练次数
+        std::string RespiratoryTrainingTime{nullptr};
+        std::string HeartRateValue{nullptr};
+    };
+}
+
+#endif
\ No newline at end of file
index 99acee8..51c7517 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-08 09:36:01
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 18:09:42
+ * @LastEditTime: 2024-06-12 10:37:30
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/include/RespiratoryTrainingView.h
  */
 
 #include "components/ui_image_view.h"
 #include "components/root_view.h"
 #include "hal_tick.h"
+#include "components/ui_scroll_view.h"
+#include "respiratorytraining/include/RespiratoryTrainingCompletedView.h"
 
 namespace OHOS
 {
+    typedef enum
+    {
+        RESPIRATORYTRAINING = 0, 
+        RESPIRATORYTRAININGCOMPLETED,        
+        MAX_RESPIRATORYTRAININGID,
+    } RESPIRATORYTRAININGVIEWID;
+
     class RespiratoryTrainingCallback : public AnimatorCallback
     {
     public:
@@ -41,7 +50,7 @@ namespace OHOS
         int16_t step = -1;
         float scale = 0;
         uint16_t curTime = 0;
-        uint16_t durationTime = 4*1000; // 4000: means 4000ms
+        uint16_t durationTime = 5 * 1000; // 5000: means 5000ms
         int16_t startVal = durationTime;
         int16_t endVal = durationTime / 2; // 2: half
     };
@@ -62,7 +71,12 @@ namespace OHOS
         RespiratoryTrainingView();
         virtual ~RespiratoryTrainingView();
         static RespiratoryTrainingView *GetInstance(void);
-
+        bool ClickFunc(int16_t interface);
+        void ChangeView(int16_t hideView, int16_t showView);
+        bool ChangeRespiratoryTrainingView(int16_t thisView);
+        bool ChangeRespiratoryTrainingCompletedView(int16_t thisView);
+        Animator *GetRespiratoryTrainingAnimator_();
+        bool StartRespiratoryTraining();
         void OnStart() override;
         void OnSetUpView() override;
         void OnTearDownView() override;
@@ -87,10 +101,14 @@ namespace OHOS
 #endif
         void InitRespiratoryTrainingElements();
         void InitRespiratoryTrainingCallBackAndAnimator();
+        void InitRespiratoryTrainingScrollView();
+        UIScrollView *RespiratoryTrainingScrollView[MAX_RESPIRATORYTRAININGID]{nullptr};
+        RespiratoryTrainingCompletedView *p_RespiratoryTrainingCompletedView{nullptr};
         RespiratoryTrainingCallback *RespiratoryTrainingCallBack_ = nullptr;
         Animator *RespiratoryTrainingAnimator_ = nullptr;
         UIImageView *RespiratoryTrainingImg_ = nullptr;
-        UILabelButton *RespiratoryTrainingStart_ = nullptr;
+        //UILabelButton *RespiratoryTrainingStart_ = nullptr;
+        UILabelExt *RespiratoryTrainingStartNote_ = nullptr;
         UILabelExt *RespiratoryTrainingLabel_ = nullptr;
         bool animateStart_ = false;
     };
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingCompletedView.cpp b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingCompletedView.cpp
new file mode 100644 (file)
index 0000000..2414334
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-05-07 11:25:58
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 10:25:32
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTrainingCompleted/src/RespiratoryTrainingCompletedView.cpp
+ */
+
+#include "respiratorytraining/include/RespiratoryTrainingCompletedView.h"
+#include "wearable_log.h"
+#include "language/font/ui_resource_string.h"
+#include "respiratorytraining/include/RespiratoryTrainingPresenter.h"
+#include "common/image_cache_manager.h"
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+
+namespace OHOS
+{
+
+    static RespiratoryTrainingCompletedView *g_pRespiratoryTrainingCompletedView{nullptr};
+
+    RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedView");
+        g_pRespiratoryTrainingCompletedView = this;
+    }
+
+    RespiratoryTrainingCompletedView::~RespiratoryTrainingCompletedView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::~RespiratoryTrainingCompletedView");
+        ClearAll();
+        g_pRespiratoryTrainingCompletedView = nullptr;
+    }
+
+    RespiratoryTrainingCompletedView *RespiratoryTrainingCompletedView::GetInstance()
+    {
+        return g_pRespiratoryTrainingCompletedView;
+    }
+
+    void RespiratoryTrainingCompletedView::ClearAll(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::ClearAll Start!!");
+        if (ScrollView != nullptr)
+        {
+            ScrollView->RemoveAll();
+            ImageCacheManager::GetInstance().UnloadSingleRes(RTCVectorImagePath);
+            ImageCacheManager::GetInstance().UnloadSingleRes(RTCGroupListImagePath);
+
+            if (Title != nullptr)
+            {
+                delete Title;
+                Title = nullptr;
+            }
+
+            if (RespiratoryTrainingImage != nullptr)
+            {
+                delete RespiratoryTrainingImage;
+                RespiratoryTrainingImage = nullptr;
+            }
+
+            if (RespiratoryTrainingLabel != nullptr)
+            {
+                delete RespiratoryTrainingLabel;
+                RespiratoryTrainingLabel = nullptr;
+            }
+            for (int i = 0; i < MAX_NUM; i++)
+            {
+                if (RTCStaticLabelView[i] != nullptr)
+                {
+                    delete RTCStaticLabelView[i];
+                    RTCStaticLabelView[i] = nullptr;
+                }
+
+                if (RTCDynamicLabelView[i] != nullptr)
+                {
+                    delete RTCDynamicLabelView[i];
+                    RTCDynamicLabelView[i] = nullptr;
+                }
+
+                if (RTCImageView[i] != nullptr)
+                {
+                    delete RTCImageView[i];
+                    RTCImageView[i] = nullptr;
+                }
+            }
+
+            if (RTCLabelButton != nullptr)
+            {
+                delete RTCLabelButton;
+                RTCLabelButton = nullptr;
+            }
+
+            delete ScrollView;
+            ScrollView = nullptr;
+        }
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::ClearAll End!!");
+    }
+
+    UILabelExt *RespiratoryTrainingCompletedView::LabelExtViewInit(const LabelConfig &labelconfig)
+    {
+        UILabelExt *label = new UILabelExt();
+        if (label == nullptr)
+        {
+            return nullptr;
+        }
+        label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height); // 位置大小
+        label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);                                       // 字体大小
+        label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);                                    // 字体行高
+        label->SetTextId(labelconfig.textId);                                                         // 内容
+        label->SetLineBreakMode(labelconfig.lineBreakMode);                                           // 断行模式。
+        label->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+        label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+        return label;
+    }
+
+    UILabel *RespiratoryTrainingCompletedView::LabelViewInit(const LabelConfig &labelconfig)
+    {
+        UILabel *label = new UILabel();
+        if (label == nullptr)
+        {
+            return nullptr;
+        }
+        label->SetPosition(labelconfig.left, labelconfig.top, labelconfig.width, labelconfig.height); // 位置大小
+        label->SetStyle(STYLE_TEXT_FONT, labelconfig.fontSize);                                       // 字体大小
+        label->SetStyle(STYLE_LINE_HEIGHT, labelconfig.lineHeigh);                                    // 字体行高
+        label->SetText(labelconfig.text);                                                             // 内容
+        label->SetLineBreakMode(labelconfig.lineBreakMode);                                           // 断行模式。
+        label->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+        label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, labelconfig.fontSize);
+        return label;
+    }
+
+    UIImageView *RespiratoryTrainingCompletedView::ImageViewInit(ImageConfig &imageconfig)
+    {
+        UIImageView *Image = new UIImageView();
+        if (Image == nullptr)
+        {
+            return nullptr;
+        }
+        Image->SetPosition(imageconfig.x, imageconfig.y, imageconfig.w, imageconfig.h);
+        return Image;
+    }
+
+    bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView");
+        ScrollView = new UIScrollView();
+        if (ScrollView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScrollView new fail!");
+            return false;
+        }
+        ScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        ScrollView->SetScrollBlankSize(75);
+        ScrollView->SetReboundSize(35);
+        ScrollView->SetHorizontalScrollState(false);
+        ScrollView->SetTouchable(true);
+        ScrollView->SetDraggable(true);
+
+        return true;
+    }
+
+    bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelView");
+        /* ---------------------------------- Title --------------------------------- */
+        LabelConfig labelconfig = {
+            .left = 83,
+            .top = 52,
+            .width = 300,
+            .height = 35,
+            .fontSize = 30,
+            .lineHeigh = 35,
+            .textId = STR_TRAINING_COMPLETE, // 训练完成
+            .lineBreakMode = UILabel::LINE_BREAK_MARQUEE,
+        };
+        Title = LabelExtViewInit(labelconfig);
+        if (nullptr == Title)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Title is nullptr!");
+            return false;
+        }
+        Title->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        ScrollView->Add(Title);
+        /* ------------------------ RespiratoryTrainingLabel ------------------------ */
+        labelconfig.left = 147;
+        labelconfig.top = 150;
+        labelconfig.width = 240;
+        labelconfig.textId = STR_BREATH_TRAINING; // 呼吸训练
+        RespiratoryTrainingLabel = LabelExtViewInit(labelconfig);
+        if (nullptr == RespiratoryTrainingLabel)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingLabel is nullptr!");
+            return false;
+        }
+        ScrollView->Add(RespiratoryTrainingLabel);
+        /* -------------------------------------------------------------------------- */
+        int y1 = 248, y2 = 286;
+        const int textId[MAX_NUM] = {STR_THIS_BREATH, STR_MEAN_HEART_RATE_MIN, STR_TODAYS_BREATHING_TRAINING};
+        std::string heartRateValue = RespiratoryTrainingModel::GetInstance().GetHeartRateValue();
+        std::string trainingTotalTime = RespiratoryTrainingModel::GetInstance().GetRespiratoryTrainingTotalTime();
+        const char *text[MAX_NUM] = {"01:00", heartRateValue.c_str(), trainingTotalTime.c_str()};
+        OHOS::ColorType RTCDynamicLabelTextColor[MAX_NUM] = {
+            Color::GetColorFromRGBA(0x1d, 0xda, 0xc4, 0xff),
+            Color::GetColorFromRGBA(0xff, 0x5a, 0x36, 0xff),
+            Color::GetColorFromRGBA(0xff, 0x8a, 0x36, 0xff),
+        };
+        for (int i = 0; i < MAX_NUM; i++)
+        {
+            labelconfig.left = 138;
+            labelconfig.top = y1 + 130 * i;
+            labelconfig.width = 240;
+            labelconfig.height = 35;
+            labelconfig.fontSize = 30;
+            labelconfig.lineHeigh = 35;
+            labelconfig.textId = textId[i];
+            labelconfig.lineBreakMode = UILabel::LINE_BREAK_MARQUEE;
+            RTCStaticLabelView[i] = LabelExtViewInit(labelconfig);
+            if (nullptr == RTCStaticLabelView[i])
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCStaticLabelView[%d] is nullptr!", i);
+                return false;
+            }
+            RTCStaticLabelView[i]->SetTextColor(Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0x7f));
+            ScrollView->Add(RTCStaticLabelView[i]);
+            /* -------------------------------------------------------------------------- */
+            labelconfig.left = 138;
+            labelconfig.top = y2 + 130 * i;
+            labelconfig.height = 47;
+            labelconfig.fontSize = 40;
+            labelconfig.lineHeigh = 47;
+            labelconfig.text = text[i];
+            RTCDynamicLabelView[i] = LabelViewInit(labelconfig);
+            if (nullptr == RTCDynamicLabelView[i])
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCDynamicLabelView[%d] is nullptr!", i);
+                return false;
+            }
+            RTCDynamicLabelView[i]->SetTextColor(RTCDynamicLabelTextColor[i]);
+            ScrollView->Add(RTCDynamicLabelView[i]);
+        }
+        return true;
+    }
+
+    bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedImageView()
+    {
+        RespiratoryTrainingImage = new UIImageView();
+        if (RespiratoryTrainingImage == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingImage is nullptr!!");
+            return false;
+        }
+        RespiratoryTrainingImage->SetPosition(61, 122, 90, 90);
+        RespiratoryTrainingImage->SetAutoEnable(false);
+        RespiratoryTrainingImage->SetResizeMode(UIImageView::CENTER);
+        ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(RTCVectorImagePath);
+        if (imgInfo == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Load image failed!");
+            return false;
+        }
+        RespiratoryTrainingImage->SetSrc(imgInfo);
+        ScrollView->Add(RespiratoryTrainingImage);
+        /* -------------------------------------------------------------------------- */
+        ImageConfig imageconfig = {
+            .x = 89,
+            .y = 212,
+            .w = 42,
+            .h = 130,
+        };
+        // 加载呼吸训练Vector图片
+        imgInfo = ImageCacheManager::GetInstance().LoadSingleRes(RTCGroupListImagePath);
+        for (int i = 0; i < MAX_NUM; i++)
+        {
+            imageconfig.y = 212 + (i * 130);
+            RTCImageView[i] = ImageViewInit(imageconfig);
+            if (RTCImageView[i] == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCImageView[%d] is nullptr!", i);
+                return false;
+            }
+            RTCImageView[i]->SetSrc(imgInfo);
+            ScrollView->Add(RTCImageView[i]);
+        }
+        return true;
+    }
+
+    bool RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelButtonView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedLabelButtonView");
+        RTCLabelButton = new UILabelButtonExt();
+        if (RTCLabelButton == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RTCLabelButton is nullptr!");
+            return false;
+        }
+        RTCLabelButton->SetPosition(43, 622);
+        RTCLabelButton->Resize(380, 100);
+        RTCLabelButton->SetViewId(RTCLABELBUTTON);
+        RTCLabelButton->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+        // RTCLabelButton->SetText("关闭");
+        RTCLabelButton->SetTextId(STR_CLOSE);
+        RTCLabelButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        RTCLabelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED);
+        RTCLabelButton->SetStyleForState(STYLE_BORDER_COLOR, 0xffffffff, UIButton::PRESSED);
+        RTCLabelButton->SetStyleForState(STYLE_BORDER_OPA, 0x00, UIButton::PRESSED);
+        UIView::OnClickListener *labelButtonClick = static_cast<UIView::OnClickListener *>(RespiratoryTrainingPresenter::GetInstance());
+        if (labelButtonClick == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "labelButtonClick is nullptr!");
+            return false;
+        }
+        RTCLabelButton->SetOnClickListener(labelButtonClick);
+        ScrollView->Add(RTCLabelButton);
+        return true;
+    }
+
+    // 呼吸训练完成视图初始化
+    UIScrollView *RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedViewInit(void)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::RespiratoryTrainingCompletedViewInit");
+        if (!CreateRespiratoryTrainingCompletedScrollView() || !CreateRespiratoryTrainingCompletedLabelView() ||
+            !CreateRespiratoryTrainingCompletedImageView() || !CreateRespiratoryTrainingCompletedLabelButtonView())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedViewInit fail!!");
+            return nullptr;
+        }
+        return ScrollView;
+    }
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp
new file mode 100644 (file)
index 0000000..65e03b6
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-11 16:26:20
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-06-12 11:00:29
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/respiratorytraining/src/RespiratoryTrainingModel.cpp
+ */
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+#include "wearable_log.h"
+#include <cmsis_os2.h>
+#include <cmsis_os.h>
+#include <ohos_types.h>
+#include <service/graphic_service.h>
+#include <iostream>
+#include "respiratorytraining/include/RespiratoryTrainingView.h"
+namespace OHOS
+{
+    // 声明定时器变量
+    static osTimerId_t g_timer = NULL;
+    static int Time = 5;
+    static constexpr int ONE_MINUTE = 60; // 一分钟
+    static bool START_FLAG = false;
+
+    RespiratoryTrainingModel::RespiratoryTrainingModel() {}
+
+    RespiratoryTrainingModel::~RespiratoryTrainingModel() {}
+
+    RespiratoryTrainingModel &RespiratoryTrainingModel::GetInstance()
+    {
+        static RespiratoryTrainingModel instance;
+        return instance;
+    }
+
+    // 每进行一次呼吸训练,呼吸训练次数自加1
+    void RespiratoryTrainingModel::AddRespiratoryTrainingTimes()
+    {
+        RespiratoryTrainingTimes += 1;
+    }
+
+    // 获取呼吸训练总时间
+    std::string RespiratoryTrainingModel::GetRespiratoryTrainingTotalTime(void)
+    {
+        RespiratoryTrainingTime = std::to_string(RespiratoryTrainingTimes) + "min";
+        return RespiratoryTrainingTime;
+    }
+
+    // 获取心率值
+    std::string RespiratoryTrainingModel::GetHeartRateValue(void)
+    {
+        HeartRateValue = "144";
+        return HeartRateValue;
+    }
+
+    void RespiratoryTrainingModel::ResumeStatus()
+    {
+        Time = 5;
+        START_FLAG = false;
+    }
+    /* -------------------------------------------------------------------------- */
+    /*定时器到期时的处理*/
+    static void RT_TimerCallbackProc(int data)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RT_TimerCallbackProc,Time = %d", Time);
+        Time -= 1;
+        RespiratoryTrainingView *p_RespiratoryTrainingView = RespiratoryTrainingView::GetInstance();
+        if (p_RespiratoryTrainingView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "p_RespiratoryTrainingView is nullptr!!");
+            return;
+        }
+        if (Time <= 0)
+        {
+            if (START_FLAG == true)
+            {
+                RespiratoryTrainingModel::GetInstance().RT_StopTimer(); // 停止定时器
+                RespiratoryTrainingModel::GetInstance().AddRespiratoryTrainingTimes();
+                p_RespiratoryTrainingView->GetRespiratoryTrainingAnimator_()->Stop();
+                p_RespiratoryTrainingView->ChangeView(RESPIRATORYTRAINING, RESPIRATORYTRAININGCOMPLETED);
+            }
+            else
+            {
+                Time = ONE_MINUTE;
+                p_RespiratoryTrainingView->StartRespiratoryTraining();
+                START_FLAG = true;
+            }
+        }
+
+        return;
+    }
+
+    /*
+     * @brief 回调函数
+     */
+    static void RT_TimerCallback(int data)
+    {
+        GraphicService::GetInstance()->PostGraphicEvent(std::bind(RT_TimerCallbackProc, data));
+    }
+
+    /*
+     *  @brief 开启定时器函数
+     *  @param interval 时间间隔,单位ms
+     */
+    void RespiratoryTrainingModel::RT_StartTimer(uint32_t interval)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingModel::RT_StartTimer");
+        /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */
+        if (g_timer != NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+            return;
+        }
+
+        /* --------------------------------- 2.创建定时器 -------------------------------- */
+        g_timer = osTimerNew((osTimerFunc_t)RT_TimerCallback, osTimerPeriodic, NULL, NULL);
+        // 检查定时器创建是否成功
+        if (g_timer == NULL)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+            return;
+        }
+
+        /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */
+        int tick = osMs2Tick(interval);
+
+        /* --------------------------------- 4.启动定时器 -------------------------------- */
+        osStatus_t ret = osTimerStart(g_timer, tick);
+        /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 NULL -------------------- */
+        if (ret != osOK)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            if (g_timer != NULL)
+            {
+                ret = osTimerDelete(g_timer);
+            }
+            g_timer = NULL;
+            return;
+        }
+    }
+
+    /*
+     * @brief 停止定时器
+     */
+    void RespiratoryTrainingModel::RT_StopTimer(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingModel::RT_StopTimer");
+        // 检查定时器是否存在
+        if (g_timer != NULL)
+        {
+            // 删除定时器并置为 NULL
+            osStatus_t ret = osTimerDelete(g_timer);
+            if (ret != osOK)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
+            }
+            g_timer = NULL;
+        }
+    }
+}
index a1f9778..68bc55d 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:26:06
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 16:07:50
+ * @LastEditTime: 2024-06-12 11:13:13
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingPresenter.cpp
  */
 
@@ -13,7 +13,9 @@
 #include "common/key_code.h"
 #include <custom_utils.h>
 #include "UiConfig.h"
-
+#include <iostream>
+#include <string>
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
 namespace OHOS
 {
 
@@ -55,11 +57,18 @@ namespace OHOS
     {
         Presenter<RespiratoryTrainingView>::OnStop();
         ScreenAlwaysOnCtr(0);
+        RespiratoryTrainingModel::GetInstance().RT_StopTimer();
+        RespiratoryTrainingModel::GetInstance().ResumeStatus();
     }
 
     bool RespiratoryTrainingPresenter::OnClick(UIView &view, const ClickEvent &event)
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingPresenter::OnClick");
+        std::string viewId = view.GetViewId();
+        if(viewId == RTCLABELBUTTON)
+        {
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+        }
         return true;
     }
 
index 66d8dc9..a34ef22 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-08 17:10:04
+ * @LastEditTime: 2024-06-12 11:09:19
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/RespiratoryTraining/src/RespiratoryTrainingView.cpp
  */
 
 #include "common/image_cache_manager.h"
 #include "animator/easing_equation.h"
 #include "language/font/ui_resource_string.h"
+#include "respiratorytraining/include/RespiratoryTrainingModel.h"
+
 namespace OHOS
 {
 
+    static constexpr uint16_t ONE_SECOND = 1000; // 一秒
     static RespiratoryTrainingView *g_pRespiratoryTrainingView{nullptr};
 
     RespiratoryTrainingView::RespiratoryTrainingView()
@@ -34,9 +37,92 @@ namespace OHOS
         return g_pRespiratoryTrainingView;
     }
 
+    bool RespiratoryTrainingView::ChangeRespiratoryTrainingView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeRespiratoryTrainingView");
+        if (RespiratoryTrainingScrollView[thisView] == nullptr)
+        {
+            container_->Add(RespiratoryTrainingScrollView[thisView]);
+        }
+        return true;
+    }
+
+    bool RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView(int16_t thisView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView");
+        if (RespiratoryTrainingScrollView[thisView] == nullptr)
+        {
+            p_RespiratoryTrainingCompletedView = new RespiratoryTrainingCompletedView();
+            if (p_RespiratoryTrainingCompletedView == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new scrollView[%d] fail", thisView);
+                return false;
+            }
+            RespiratoryTrainingScrollView[thisView] = p_RespiratoryTrainingCompletedView->RespiratoryTrainingCompletedViewInit();
+            container_->Add(RespiratoryTrainingScrollView[thisView]);
+        }
+        return true;
+    }
+
+    struct RespiratoryTrainingViewMapper
+    {
+        const int16_t viewId;
+        bool (RespiratoryTrainingView::*func)(int16_t thisView);
+    };
+
+    static const RespiratoryTrainingViewMapper ViewMapper[] = {
+        {RESPIRATORYTRAINING, &RespiratoryTrainingView::ChangeRespiratoryTrainingView},
+        {RESPIRATORYTRAININGCOMPLETED, &RespiratoryTrainingView::ChangeRespiratoryTrainingCompletedView},
+    };
+
+    // 3.根据传入的interface参数执行相应视图ID关联的成员函数。
+    bool RespiratoryTrainingView::ClickFunc(int16_t interface)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ClickFunc");
+        int funcSize = sizeof(ViewMapper) / sizeof(ViewMapper[0]);
+        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;
+    }
+
+    void RespiratoryTrainingView::ChangeView(int16_t hideView, int16_t showView)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::ChangeView");
+        if (hideView > MAX_RESPIRATORYTRAININGID)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+            return;
+        }
+        RespiratoryTrainingScrollView[hideView]->SetVisible(false);
+        ClickFunc(showView);
+        RespiratoryTrainingScrollView[showView]->SetVisible(true);
+        Draw();
+    }
+
+    Animator *RespiratoryTrainingView::GetRespiratoryTrainingAnimator_()
+    {
+        if (RespiratoryTrainingAnimator_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingAnimator_ is nullptr!!");
+            return nullptr;
+        }
+        return RespiratoryTrainingAnimator_;
+    }
+
     // 设置按键监听
     static void SetKeyActListener()
     {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetKeyActListener");
         RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::RespiratoryTrainingPresenter::GetInstance();
         RootView::GetInstance()->SetOnKeyActListener(keyactListener);
     }
@@ -230,16 +316,17 @@ namespace OHOS
 
     bool RespiratoryTrainingView::OnClick(UIView &view, const ClickEvent &event)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnClick");
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::OnClick");
         UNUSED(view);
         UNUSED(event);
+#if 0
         if (!animateStart_)
         {
             RespiratoryTrainingAnimator_->Start();
             animateStart_ = false;
             if (RespiratoryTrainingStart_ != nullptr)
             {
-                container_->Remove(RespiratoryTrainingStart_);
+                RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Remove(RespiratoryTrainingStart_);
                 delete RespiratoryTrainingStart_;
                 RespiratoryTrainingStart_ = nullptr;
             }
@@ -250,7 +337,7 @@ namespace OHOS
                 return false;
             }
             RespiratoryTrainingLabel_->SetPosition(53, 320, 360, 70); // 180, 380, 100, 50: left, right, width, height
-            // RespiratoryTrainingLabel_->SetText("现在呼气气");
+            // RespiratoryTrainingLabel_->SetText("现在呼气");
             RespiratoryTrainingLabel_->SetTextId(STR_EXHALE_NOW);
             RespiratoryTrainingLabel_->SetStyle(STYLE_TEXT_FONT, 30);
             RespiratoryTrainingLabel_->SetStyle(STYLE_LINE_HEIGHT, 35);
@@ -258,14 +345,52 @@ namespace OHOS
             RespiratoryTrainingLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
             RespiratoryTrainingLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
             RespiratoryTrainingLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
-            container_->Add(RespiratoryTrainingLabel_);
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingLabel_);
             RespiratoryTrainingCallBack_->SetTextView(RespiratoryTrainingLabel_);
             RespiratoryTrainingCallBack_->startTimestamp = HALTick::GetInstance().GetTime();
-            container_->Invalidate();
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Invalidate();
         }
+#endif
         return true;
     }
 
+    // 开始呼吸训练
+    bool RespiratoryTrainingView::StartRespiratoryTraining()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::StartRespiratoryTraining");
+        if (!animateStart_)
+        {
+            RespiratoryTrainingAnimator_->Start();
+            animateStart_ = true;
+            if (RespiratoryTrainingStartNote_ != nullptr)
+            {
+                RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Remove(RespiratoryTrainingStartNote_);
+                delete RespiratoryTrainingStartNote_;
+                RespiratoryTrainingStartNote_ = nullptr;
+            }
+            RespiratoryTrainingLabel_ = new UILabelExt();
+            if (RespiratoryTrainingLabel_ == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingLabel_ new fail");
+                return false;
+            }
+            RespiratoryTrainingLabel_->SetPosition(53, 320, 360, 70);
+            RespiratoryTrainingLabel_->SetTextId(STR_EXHALE_NOW); // 现在呼气
+            RespiratoryTrainingLabel_->SetStyle(STYLE_TEXT_FONT, 30);
+            RespiratoryTrainingLabel_->SetStyle(STYLE_LINE_HEIGHT, 35);
+            RespiratoryTrainingLabel_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+            RespiratoryTrainingLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+            RespiratoryTrainingLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+            RespiratoryTrainingLabel_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingLabel_);
+            RespiratoryTrainingCallBack_->SetTextView(RespiratoryTrainingLabel_);
+            RespiratoryTrainingCallBack_->startTimestamp = HALTick::GetInstance().GetTime();
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Invalidate();
+        }
+        return true;
+    }
+
+    // 初始化呼吸训练元素
     void RespiratoryTrainingView::InitRespiratoryTrainingElements()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::InitRespiratoryTrainingElements");
@@ -290,8 +415,9 @@ namespace OHOS
         RespiratoryTrainingImg_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
         RespiratoryTrainingImg_->SetAutoEnable(false);
         RespiratoryTrainingImg_->SetResizeMode(UIImageView::ImageResizeMode::CENTER);
-        container_->Add(RespiratoryTrainingImg_);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingImg_);
 
+#if 0
         // 创建并设置呼吸训练开始按钮
         RespiratoryTrainingStart_ = new UILabelButton();
         if (RespiratoryTrainingStart_ == nullptr)
@@ -303,7 +429,25 @@ namespace OHOS
         RespiratoryTrainingStart_->SetText("Start");
         RespiratoryTrainingStart_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
         RespiratoryTrainingStart_->SetOnClickListener(this);
-        container_->Add(RespiratoryTrainingStart_);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingStart_);
+#elif 1
+
+        RespiratoryTrainingStartNote_ = new UILabelExt();
+        if (RespiratoryTrainingStartNote_ == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingStartNote_ new failed!");
+            return;
+        }
+        RespiratoryTrainingStartNote_->SetPosition(53, 320, 360, 70);
+        RespiratoryTrainingStartNote_->SetStyle(STYLE_TEXT_FONT, 30);
+        RespiratoryTrainingStartNote_->SetStyle(STYLE_LINE_HEIGHT, 35);
+        // RespiratoryTrainingStartNote_->SetText("保持不动,将注意力集中在呼吸上");
+        RespiratoryTrainingStartNote_->SetTextId(STR_KEEP_STILL_FOCUS_ON_BREATHING);
+        RespiratoryTrainingStartNote_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+        RespiratoryTrainingStartNote_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        RespiratoryTrainingStartNote_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->Add(RespiratoryTrainingStartNote_);
+#endif
     }
 
     void RespiratoryTrainingView::InitRespiratoryTrainingCallBackAndAnimator()
@@ -328,16 +472,36 @@ namespace OHOS
         animateStart_ = false;
     }
 
+    void RespiratoryTrainingView::InitRespiratoryTrainingScrollView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingCompletedView::CreateRespiratoryTrainingCompletedScrollView");
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING] = new UIScrollView();
+        if (RespiratoryTrainingScrollView[RESPIRATORYTRAINING] == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LanguageSwitchView::ScrollView new fail!");
+            return;
+        }
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetScrollBlankSize(50);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetReboundSize(35);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetHorizontalScrollState(false);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetTouchable(true);
+        RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->SetDraggable(true);
+        container_->Add(RespiratoryTrainingScrollView[RESPIRATORYTRAINING]);
+    }
+
     void RespiratoryTrainingView::RespiratoryTrainingViewInit(void)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "RespiratoryTrainingView::RespiratoryTrainingViewInit");
+        InitRespiratoryTrainingScrollView();
         InitRespiratoryTrainingElements();
         InitRespiratoryTrainingCallBackAndAnimator();
+        RespiratoryTrainingModel::GetInstance().RT_StartTimer(ONE_SECOND);
     }
 
     void RespiratoryTrainingView::ClearAll(void)
     {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll start");
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll start");
         if (container_ != nullptr)
         {
             container_->RemoveAll();
@@ -345,6 +509,13 @@ namespace OHOS
             container_ = nullptr;
         }
 
+        if (RespiratoryTrainingScrollView[RESPIRATORYTRAINING] != nullptr)
+        {
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING]->RemoveAll();
+            delete RespiratoryTrainingScrollView[RESPIRATORYTRAINING];
+            RespiratoryTrainingScrollView[RESPIRATORYTRAINING] = nullptr;
+        }
+
         if (RespiratoryTrainingAnimator_ != nullptr)
         {
             RespiratoryTrainingAnimator_->Stop();
@@ -370,7 +541,16 @@ namespace OHOS
             delete RespiratoryTrainingLabel_;
             RespiratoryTrainingLabel_ = nullptr;
         }
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll end!!");
+
+        if (p_RespiratoryTrainingCompletedView != nullptr)
+        {
+            delete p_RespiratoryTrainingCompletedView;
+            p_RespiratoryTrainingCompletedView = nullptr;
+
+            RespiratoryTrainingScrollView[RESPIRATORYTRAININGCOMPLETED] = nullptr;
+        }
+
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[RespiratoryTrainingView]ClearAll end!!");
     }
 
     void RespiratoryTrainingView::OnStart()
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCGroupList.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCGroupList.bin
new file mode 100644 (file)
index 0000000..02e75c2
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:15470adf52f28d869bfc75426d39f2fc911113095200d019de832796160a5b71
+size 4776
diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCVector.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/RespiratoryTraining/RTCVector.bin
new file mode 100644 (file)
index 0000000..d8bd496
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:22262add581a16dbb792eb87ace656dcefe6befd7fa4d13fe893728028e26208
+size 1896