#include "TjdUiAppSportView.h" #include "NativeAbility.h" #include "TjdUiAppIds.h" #include "TjdUiAppSportDrawGuiAPI.h" #include "TjdUiAppSportModel.h" #include "TjdUiAppSportPage.h" #include "TjdUiMemManage.h" #include "TjdUiMultiLanguageExt.h" #include "TjdUiUtils.h" #include "ble_api.h" #include "color.h" #include "common/image_cache_manager.h" #include "graphic_service.h" #include "los_typedef.h" #include "service_sport.h" #include "sql_fit.h" #include "style.h" #include "sys/stat.h" #include "sys_config.h" #include "ui_screennotify.h" #include "wearable_log.h" #include #include #include #include #include #include #include #include using namespace OHOS; #define DEBUG 1 #define ENABLE_PRINT_INFO 1 #if ENABLE_PRINT_INFO #define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制 #define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开 #define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开 #define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印 #else #define static_print_info(...) #define static_print_warn(...) #define static_print_error(...) #define static_print_debug(...) #endif namespace TJD { #define TJD_FS_DIR_SPORT "/system/tjd_sport" #define CONFIRM_CANCEL_RES_BIN_PATH TJD_IMAGE_PATH "img_confirm_cancel.bin" #define SPORT_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_sport.bin" #define BATTERY_IMAGE_BIN_PATH TJD_IMAGE_PATH "img_sport_battery.bin" #define SPORT_DATA_JSON_PATH "/system/tjd_sport/sport_data.json" static uint32_t g_comeback_dial_interval = 5; static uint32_t timerCount = 0; static OHOS::GraphicTimer *sportingTimer_ = nullptr; // 运动进行中计时器 static OHOS::GraphicTimer *gpsTimer_ = nullptr; // GPS定位计时器 static TjdUiAppSportView *g_pv_AppSportView = nullptr; static EndOfSportDataView *g_EndOfSportDataView = nullptr; static CountDownView *g_pv_CountDownView = nullptr; static SportingView *g_pv_SportingView = nullptr; static EditSportView *g_pv_EditSportView = nullptr; static SportList *g_pv_SportList = nullptr; static GPSView *g_pv_GPSView = nullptr; SportViewManager TjdUiAppSportView::currentViewIndex_ = VIEW_MANAGER_MAX; SportViewManager TjdUiAppSportView::lastViewIndex_ = VIEW_MANAGER_MAX; SportTypeIndex TjdUiAppSportView::currentIconIndex_ = SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX; int SportingView::lastTime = 0; SportType SportingView::sportType = SPORT_TYPE_MAX; SportingData_t lastSportingData; // 记录上一次的运动数据; extern bool returnToDial; const static int16_t CENTER_X = 233; const static int16_t CENTER_Y = 233; const static int16_t LABEL_X = 204; // label的x坐标 const static int16_t LABEL_Y = 156; // label的y坐标 const static int16_t RADIUS = 144; const static int16_t STROKE_WIDTH = 22; const static int16_t CIRCLE_BASE_WIDTH = 22; const static uint32_t LIGHT_GREEN = 0xFF2d4d0a; static const uint16_t LABEL_FONT_SIZE = 100; static const uint16_t ANIMATE_TIME = 500; static const uint16_t SECOND_TO_MINISECOND = 1000; static const uint16_t CIRCLE_FADE_OUT = 200; static const uint16_t DEGREES_PER_CIRCLE = 360; static uint16_t GPS_CAVAS_WIDTH = 136; static uint16_t GPS_CAVAS_HEIGHT = 160; // clang-format off bool SportUIScrollView::OnDragStartEvent(const OHOS::DragEvent &event) { if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) { return true; } isOnStart_ = true; return OHOS::UIScrollViewNested::OnDragStartEvent(event); } bool SportUIScrollView::OnDragEvent(const OHOS::DragEvent &event) { if (!isOnStart_) { return true; } if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) { return true; } return OHOS::UIScrollViewNested::OnDragEvent(event); } bool SportUIScrollView::OnDragEndEvent(const OHOS::DragEvent &event) { if (!isOnStart_) { return true; } isOnStart_ = false; if (TjdUiAppSportView::currentViewIndex_ != SPORT_LIST_VIEW) { return true; } return OHOS::UIScrollViewNested::OnDragEndEvent(event); } #pragma region 主界面 TjdUiAppSportView::TjdUiAppSportView(){ static_print_info("==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_AppSportView = this;} TjdUiAppSportView::~TjdUiAppSportView(){ static_print_info("==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_AppSportView = nullptr;} TjdUiAppSportView *TjdUiAppSportView::GetInstance(void) { return g_pv_AppSportView; } // clang-format on bool SportViewOnClickedListener::OnClick(UIView &view, const ClickEvent &event) { auto sportingView = SportingView::GetInstance(); auto sportPresenter = TjdUiAppSportPresenter::GetInstance(); if (view.GetViewId() == "pauseOrContinueCheckBox_") { if (static_cast(&view)->GetState() == OHOS::UICheckBox::UICheckBoxState::SELECTED) { TjdUiAppSportModel::GetInstance()->SetIfSportSuspend(true); sportingTimer_->Stop(); SportingData_t Data = TjdUiAppSportModel::GetInstance()->GetServiceSportData(); sportingView->SportingViewDateRefresh(Data); // sportPresenter->SportingControlHandler(SportingAction::Stop, nullptr); } else { TjdUiAppSportModel::GetInstance()->SetIfSportSuspend(false); sportingTimer_->Start(); SportingView::lastTime = HALTick::GetInstance().GetTime(); sportingView->ResetSwipeView(); // sportPresenter->SportingControlHandler(SportingAction::Start, nullptr); } } else if (view.GetViewId() == "NoDataConfirm_" || view.GetViewId() == "DataConfirm_") { // if (view.GetViewId() == "DataConfirm_") { // TjdUiAppSportModel::GetInstance()->RecordSportData(); // } TjdUiAppSportView::GetInstance()->ShowTargetView(SportViewManager::SPORT_LIST_VIEW); } else if (view.GetViewId() == "imgEnlarge_") { if (GPS_CAVAS_HEIGHT >= 315 || GPS_CAVAS_WIDTH >= 251) return true; GPS_CAVAS_HEIGHT = GPS_CAVAS_HEIGHT * 1.16; GPS_CAVAS_WIDTH = GPS_CAVAS_WIDTH * 1.16; sportingView->GPSCanvasAutoCenter(); printf("OnClick viewId: %s,GPS_CAVAS_HEIGHT = %d,screenWidth = %d\n", view.GetViewId(), GPS_CAVAS_HEIGHT, GPS_CAVAS_WIDTH); } else if (view.GetViewId() == "imgShrink") { if (GPS_CAVAS_HEIGHT <= 88 || GPS_CAVAS_WIDTH <= 69) return true; GPS_CAVAS_HEIGHT = GPS_CAVAS_HEIGHT * 0.84; GPS_CAVAS_WIDTH = GPS_CAVAS_WIDTH * 0.84; sportingView->GPSCanvasAutoCenter(); printf("OnClick viewId: %s,GPS_CAVAS_HEIGHT = %d,screenWidth = %d\n", view.GetViewId(), GPS_CAVAS_HEIGHT, GPS_CAVAS_WIDTH); } return true; } void TjdUiAppSportView::OnStart() { static_print_info("TjdUiAppSportView::OnStart()"); OHOS::FocusManager::GetInstance()->ClearFocus(); if (access(TJD_FS_DIR_SPORT, 0) != 0) { mkdir(TJD_FS_DIR_SPORT, 0777); static_print_debug("mkdir /system/tjd_sport dirent success"); } TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath(); // 读取配置文件,并记录文件路径 OHOS::ImageCacheManager::GetInstance().LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH); if (access(SPORT_DATA_JSON_PATH, F_OK) != 0) TjdUiAppSportModel::GetInstance()->CreateJsonAndSaveToFile(g_pv_Sport, SPORT_MAX_INDEX); SportInfo *jsonSportInfo = TjdUiAppSportModel::GetInstance()->ReadFileAndTransformToJson(); SportDataInit(); InitSportList(jsonSportInfo); InitEditSportView(jsonSportInfo); free(jsonSportInfo); if (mainView_ == nullptr) { mainView_ = new SportUIScrollView(); } mainView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); // mainView_->SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); AddViewToRootContainer(mainView_); } void TjdUiAppSportView::SportDataInit(void) { for (auto &goal : g_pv_SportGoal) { goal.sportGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_573)); goal.heartRateRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_217)); goal.timeRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_220)); goal.distRemindGoal = std::string(FontGlobalManager::GetInstance()->GetText(STR_ID_225)); } } void TjdUiAppSportView::OnStop() { OHOS::FocusManager::GetInstance()->ClearFocus(); static_print_info("TjdUiAppSportView==line[%d]==func[%s]\n", __LINE__, __func__); OHOS::RootView::GetInstance()->Remove(mainView_); if (editItemList_) { delete editItemList_; editItemList_ = nullptr; } if (sportItemList_) { delete sportItemList_; sportItemList_ = nullptr; } if (mainView_ != nullptr) { mainView_->RemoveAll(); delete mainView_; mainView_ = nullptr; } for (int i = 1; i < VIEW_MANAGER_MAX; ++i) { if (viewManager_[i] != nullptr) { viewManager_[i]->RemoveAll(); delete viewManager_[i]; viewManager_[i] = nullptr; } } if (sportItemList_ != nullptr) { delete sportItemList_; sportItemList_ = nullptr; } for (int i = 0; i < SPORT_MAX_INDEX; ++i) { if (imgItemInfo[i] != nullptr) { delete imgItemInfo[i]; imgItemInfo[i] = nullptr; } } if (sportingTimer_ != nullptr) { sportingTimer_->Stop(); delete sportingTimer_; sportingTimer_ = nullptr; } ImageCacheManager::GetInstance().UnloadAllInMultiRes(SPORT_IMAGE_BIN_PATH); ImageCacheManager::GetInstance().UnloadAllInMultiRes(BATTERY_IMAGE_BIN_PATH); ImageCacheManager::GetInstance().UnloadAllInMultiRes(CONFIRM_CANCEL_RES_BIN_PATH); } void TjdUiAppSportView::InitSportList(SportInfo *sportInfo) { auto &image = OHOS::ImageCacheManager::GetInstance(); if (sportItemList_ == nullptr) { sportItemList_ = new std::list(); } sportItemList_->clear(); image.LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH); for (uint8_t i = 0; i < SPORT_MAX_INDEX; i++) { hashMap[static_cast(g_pv_EditItemInfo[i].index)] = i; g_pv_Sport[i].state = sportInfo[i].state; if (g_pv_Sport[i].state) { imgItemInfo[i] = image.LoadOneInMultiRes(g_pv_Sport[i].imgIconResId, SPORT_IMAGE_BIN_PATH); sportItemList_->push_back( {g_pv_Sport[i].index, imgItemInfo[i], g_pv_Sport[i].sportTypeId, g_pv_Sport[i].goalId}); } } } void TjdUiAppSportView::InitEditSportView(SportInfo *sportInfo) { auto &image = OHOS::ImageCacheManager::GetInstance(); if (editItemList_ == nullptr) { editItemList_ = new std::list(); } editItemList_->clear(); image.LoadAllInMultiRes(SPORT_IMAGE_BIN_PATH); for (uint8_t i = 0; i < MAX_SPORT_TYPE; i++) { g_pv_EditItemInfo[hashMap[i]].state = sportInfo[i].state; printf("hashMap find sport = %d, position = %d\n", i, hashMap[i]); editItemInfo[i] = image.LoadOneInMultiRes(g_pv_EditItemInfo[i].iconId, SPORT_IMAGE_BIN_PATH); editItemList_->push_back({g_pv_EditItemInfo[i].index, editItemInfo[i], g_pv_EditItemInfo[i].sportTypeId, g_pv_EditItemInfo[i].state}); } } void TjdUiAppSportView::ChooseSportItem(SportTypeIndex iconIndex) { if (iconIndex < 0 || iconIndex >= SPORT_MAX_INDEX) { return; } static_print_info("==line[%d]==func[%s]==iconIndex[[%d]]\n", __LINE__, __func__, iconIndex); switch (iconIndex) { case SPORT_TYPE_03_INDOOR_CYCLING_INDEX: case SPORT_TYPE_11_CYCLING_INDEX: case SPORT_TYPE_38_FRISBEE_INDEX: tjd_driver_hr_api_get_ops()->sport_mode_set(RIDE_MODE); break; case SPORT_TYPE_13_STAIRCASE_INDEX: case SPORT_TYPE_16_STEPPER_INDEX: case SPORT_TYPE_17_STROLLER_INDEX: case SPORT_TYPE_08_ELLIPTICAL_INDEX: tjd_driver_hr_api_get_ops()->sport_mode_set(WALK_MODE); break; case SPORT_TYPE_50_SKIPPING_INDEX: tjd_driver_hr_api_get_ops()->sport_mode_set(JUMP_MODE); break; case SPORT_TYPE_04_FOOTBALL_INDEX: case SPORT_TYPE_05_BASKETBALL_INDEX: case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX: case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX: case SPORT_TYPE_12_ON_FOOT_INDEX: case SPORT_TYPE_14_ROWING_MACHINE_INDEX: case SPORT_TYPE_15_JUZHONG_INDEX: case SPORT_TYPE_18_HITI_INDEX: case SPORT_TYPE_19_GYMNASTICS_INDEX: case SPORT_TYPE_20_GROUP_INDEX: case SPORT_TYPE_23_INSTRUMENT_INDEX: case SPORT_TYPE_24_TAEKWONDO_INDEX: case SPORT_TYPE_25_BOXING_INDEX: case SPORT_TYPE_26_FREE_COMBAT_INDEX: case SPORT_TYPE_27_KARATE_INDEX: case SPORT_TYPE_28_FENCING_INDEX: case SPORT_TYPE_29_CORE_TRAINING_INDEX: case SPORT_TYPE_30_KICKBOXING_INDEX: case SPORT_TYPE_37_HULA_HOOP_INDEX: case SPORT_TYPE_39_BADMINTON_INDEX: case SPORT_TYPE_40_PING_PONG_INDEX: case SPORT_TYPE_41_TENNIS_INDEX: case SPORT_TYPE_44_VOLLEYBALL_INDEX: case SPORT_TYPE_45_BASEBALL_INDEX: case SPORT_TYPE_46_RUGBY_INDEX: case SPORT_TYPE_47_HOCKEY_INDEX: case SPORT_TYPE_52_SAILBOAT_INDEX: case SPORT_TYPE_53_SURFING_INDEX: case SPORT_TYPE_56_CANOEING_INDEX: tjd_driver_hr_api_get_ops()->sport_mode_set(HIGH_POW_MODE); default: break; } ShowTargetView(COUNT_DOWN_VIEW, iconIndex); } void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex) { if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) { return; } InitTargetView(showIndex, SPORT_MAX_INDEX, 0); if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX && viewManager_[currentViewIndex_] != nullptr && showIndex != currentViewIndex_) { viewManager_[currentViewIndex_]->HideView(); } if (viewManager_[showIndex] != nullptr) { viewManager_[showIndex]->ShowView(); } currentViewIndex_ = showIndex; } void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex, uint8_t touchIndex) { if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) { return; } InitTargetView(showIndex, SPORT_MAX_INDEX, touchIndex); if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX && viewManager_[currentViewIndex_] != nullptr) { viewManager_[currentViewIndex_]->HideView(); } if (viewManager_[showIndex] != nullptr) { viewManager_[showIndex]->ShowView(); } currentViewIndex_ = showIndex; } void TjdUiAppSportView::ShowTargetView(SportViewManager showIndex, SportTypeIndex iconIndex) { static_print_info("if coming here, showIndex = %d, iconIndex = %d\n", showIndex, iconIndex); if (showIndex < 0 || showIndex >= VIEW_MANAGER_MAX) { return; } switch (iconIndex) { case SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX: case SPORT_TYPE_02_OUTDOOR_WALKING_INDEX: case SPORT_TYPE_04_FOOTBALL_INDEX: case SPORT_TYPE_05_BASKETBALL_INDEX: case SPORT_TYPE_12_ON_FOOT_INDEX: case SPORT_TYPE_13_STAIRCASE_INDEX: SportingView::sportType = SPORT_TYPE_1; showIndex = GPS_VIEW; TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_1); break; case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX: case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX: case SPORT_TYPE_11_CYCLING_INDEX: case SPORT_TYPE_51_RIDING_INDEX ... SPORT_TYPE_57_MOTORBOAT_INDEX: SportingView::sportType = SPORT_TYPE_2; showIndex = GPS_VIEW; TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_2); break; default: SportingView::sportType = SPORT_TYPE_3; showIndex = COUNT_DOWN_VIEW; TjdUiAppSportModel::GetInstance()->SportHeartRateControlHandler(SportingAction::Start, nullptr); TjdUiAppSportModel::GetInstance()->SetSportType(SPORT_TYPE_3); break; } InitTargetView(showIndex, iconIndex, iconIndex); if (currentViewIndex_ >= 0 && currentViewIndex_ < SportViewManager::VIEW_MANAGER_MAX && viewManager_[currentViewIndex_] != nullptr) { viewManager_[currentViewIndex_]->HideView(); } if (viewManager_[showIndex] != nullptr) { viewManager_[showIndex]->ShowView(); } currentViewIndex_ = showIndex; currentIconIndex_ = iconIndex; } void TjdUiAppSportView::InitTargetView(SportViewManager index, SportTypeIndex iconIndex, uint8_t touchIndex) { if (viewManager_[index] != nullptr) { return; } // clang-format off switch (index) { case SPORT_LIST_VIEW: viewManager_[index] = new SportList(); break; case COUNT_DOWN_VIEW: viewManager_[index] = new CountDownView(); break; case GPS_VIEW: viewManager_[index] = new GPSView(iconIndex); break; case SPORTING_VIEW: viewManager_[index] = new SportingView(); break; case SPORT_END_NODATA_VIEW: viewManager_[index] = new EndOfSportNoDataView(); break; case SPORT_END_DATA_VIEW: viewManager_[index] = new EndOfSportDataView(); break; case SPORT_GOAL_SELECT_VIEW: viewManager_[index] = new SportGoalSelectView(); break; case SPORT_GOAL_DISTANCES_VIEW ... SPORT_GOAL_FREE_TRAINING_VIEW: viewManager_[index] = new CommonViewGoalPage(static_cast(touchIndex)); break; case DISTANCE_GOAL_SELECT_VIEW: viewManager_[index] = new DistnaceGoalSelectView(); break; case TIME_GOAL_SELECT_VIEW: viewManager_[index] = new TimeGoalSelectView(); break; case CALORIES_GOAL_SELECT_VIEW: viewManager_[index] = new CaloriesGoalSelectView(); break; case SPORT_REMIND_SELECT_VIEW: viewManager_[index] = new RemindGoalListView(); break; case HEART_RATE_PICK_VIEW: viewManager_[index] = new HeartRatePickView(); break; case TIME_PICK_VIEW: viewManager_[index] = new TimeRemindPickView(); break; case DISTANCE_PICK_VIEW: viewManager_[index] = new DistanceRemindPickView(); break; case SPORT_EDIT_VIEW: viewManager_[index] = new EditSportView(); break; // case SPORT_FINISH_REMIND_VIEW: viewManager_[index] = new SportFinishRemindView(); break; default: break; } // clang-format on if (viewManager_[index] == nullptr) { return; } viewManager_[index]->SetPosition(0, 0); viewManager_[index]->SetVisible(false); mainView_->Add(viewManager_[index]); } Time TjdUiAppSportView::GetCurrentTime(const char *timeStr) { std::string timeString = timeStr; Time curTime; size_t firstColonPos = timeString.find(':'); if (firstColonPos != std::string::npos) { size_t secondColonPos = timeString.find(':', firstColonPos + 1); if (secondColonPos != std::string::npos) { std::string hoursStr = timeString.substr(0, firstColonPos); std::string minutesStr = timeString.substr(firstColonPos + 1, secondColonPos - firstColonPos - 1); std::string secondsStr = timeString.substr(secondColonPos + 1); curTime.hours = std::stoi(hoursStr); curTime.minutes = std::stoi(minutesStr); curTime.seconds = std::stoi(secondsStr); return curTime; } } return {0, 0, 0}; } #pragma endregion #pragma region 运动列表 #pragma region == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == SportList::SportList() { SetRotateEnable(*this); g_pv_SportList = this; SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0); if (OHOS::PageTransitionMgr::GetInstance().GetTopSlideBackImage() == nullptr) { SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); } if (listlTitle_ == nullptr) { listlTitle_ = new UILabelExt(); } // InitLabelHorCenter(*listlTitle_, 28, 17, 466, "运动"); listlTitle_->SetFont(TJD_VECTOR_FONT_FILENAME, 28); listlTitle_->SetTextId(STR_ID_05); // listlTitle_->SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); listlTitle_->SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_TOP); listlTitle_->SetPosition(0, 17, 466, 100); editBackground_.SetPosition(18, 60, 430, 160); auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BJ_EDIT, SPORT_IMAGE_BIN_PATH); imgBackground_.SetPosition(0, 0, 430, 80); if (imgInfo != nullptr) { imgBackground_.SetSrc(imgInfo); } imgBackground_.SetTouchable(true); imgBackground_.SetViewId("sport_list_edit"); imgBackground_.SetOnClickListener(TjdUiAppSportPresenter::GetInstance()); editBackground_.Add(&imgBackground_); // InitLabelHorCenter(*listlTitle_, 28, 17, 466, "运动"); lbEdit_.SetFont(TJD_VECTOR_FONT_FILENAME, 32); lbEdit_.SetTextId(STR_ID_207); lbEdit_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE); lbEdit_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); lbEdit_.SetPosition(150, 0, 130, 80); editBackground_.Add(&lbEdit_); auto sportListItemInfo_ = TjdUiAppSportView::GetInstance()->GetSportItemList(); sportAdapterPtr_ = new TjdUITransformListGroupAdapter>( *sportListItemInfo_); sportListView_ = new TjdUITransformListGroup(sportAdapterPtr_); sportListView_->AddCustomView(listlTitle_, TjdUITransformListGroup::CustomViewPos::TOP); sportListView_->AddCustomView(&editBackground_, TjdUITransformListGroup::CustomViewPos::BOTTOM); Add(sportListView_); // Add(listlTitle_); // Add(&editBackground_); // Add(&editLabel_); // Add(&listBackground_); } SportList *SportList::GetInstance() { return g_pv_SportList; } void SportList::ShowView() { OHOS::FocusManager::GetInstance()->ClearFocus(); sportListView_->RequestFocus(); sportListView_->RefreshList(); // Invalidate(); SetVisible(true); tjd_driver_hr_api_get_ops()->sport_mode_set(NORMAL_MODE); if (tjd_service_hrs_get_ops()->hrs_get_service_id() == HR_SERVICE_UI_SPORT) { tjd_service_hrs_get_ops()->close(); } } void SportList::SetListTitleVisible(bool visible) { if (visible) listlTitle_->SetVisible(true); else listlTitle_->SetVisible(false); } SportList::~SportList() { static_print_info("SportList==line[%d]==func[%s]\n", __LINE__, __func__); RemoveAll(); g_pv_SportList = nullptr; if (sportListView_ != nullptr) { sportListView_->RemoveAll(); delete sportListView_; sportListView_ = nullptr; } if (sportAdapterPtr_ != nullptr) { delete sportAdapterPtr_; sportAdapterPtr_ = nullptr; } if (listlTitle_ != nullptr) { delete listlTitle_; listlTitle_ = nullptr; } } #pragma endregion #pragma region 倒计时界面 void TJD::CountdownAnimatorCallback::Callback(UIView *view) { switch (stage_) { case countStage::STAGE_GRADUAL_CIRCLE: { GradualCircle(); break; } case countStage::STAGE_COUNTING_DOWN: { CountingDown(); break; } case countStage::STAGE_FADE_OUT: { CountDownView::GetInstance()->GetCountdownAnimator()->Stop(); TjdUiAppSportView::GetInstance()->ShowTargetView(SPORTING_VIEW); sportingTimer_->Start(); SportingView::lastTime = HALTick::GetInstance().GetTime(); // TjdUiAppSportPresenter::GetInstance()->SportingControlHandler(SportingAction::Start, nullptr); CircleFadeOut(); break; } default: break; } } void CountdownAnimatorCallback::CircleFadeOut() { uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_; if (diffTime < idleTime_) { return; } canvas_->Clear(); /* Calculate stroke width */ uint32_t curTime = diffTime - idleTime_; uint16_t width; if (curTime >= CIRCLE_FADE_OUT) { curTime = CIRCLE_FADE_OUT; stage_ = countStage::STAGE_NONE; } width = EasingEquation::QuadEaseInOut(STROKE_WIDTH, CIRCLE_BASE_WIDTH, curTime, CIRCLE_FADE_OUT); /* Draw circle */ Point center = {CENTER_X, CENTER_Y}; PaintExt paint; paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); paint.SetCapType(CAP_ROUND); paint.SetAntialiased(true); paint.SetStrokeColor(Color::GetColorFromRGB(0x94, 0xFF, 0x22)); paint.SetStrokeWidth(width); canvas_->DrawCircle(center, RADIUS, paint); uint16_t opa = OPA_OPAQUE * width / STROKE_WIDTH; if (stage_ == countStage::STAGE_NONE) { opa = OPA_TRANSPARENT; } label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 100); label_->SetStyle(STYLE_TEXT_OPA, opa); } void CountdownAnimatorCallback::UpdateLable(uint32_t curTime) { char buf[2] = {0}; // 2: buffer length uint16_t fontSize; uint16_t opa; if (curTime < ANIMATE_TIME / 2) { // 2: half time fontSize = LABEL_FONT_SIZE - LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME; // 2: half time opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE; } else { fontSize = LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME - LABEL_FONT_SIZE; // 2: half time opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE; if (updateText_) { if (sprintf_s(buf, sizeof(buf), "%u", (endAngle_ + easeDegree_) / degreePerSecond_ - 1) < 0) { return; } label_->SetText(buf); updateText_ = false; } } label_->SetFont(TJD_VECTOR_FONT_FILENAME, 100); label_->SetStyle(STYLE_TEXT_OPA, opa); } void CountdownAnimatorCallback::UpdatePath(int16_t start, int16_t end, bool needDrawCircle) { Point center = {CENTER_X, CENTER_Y}; ColorType lightGreen; lightGreen.full = LIGHT_GREEN; PaintExt paint; paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); paint.SetStrokeWidth(STROKE_WIDTH); paint.SetCapType(CAP_ROUND); paint.SetAntialiased(true); paint.SetStrokeColor(lightGreen); canvas_->Clear(); if (needDrawCircle) { canvas_->DrawCircle(center, RADIUS, paint); } if (start != end) { paint.SetStrokeColor(Color::GetColorFromRGB(0x94, 0xFF, 0x22)); if (end - start == DEGREES_PER_CIRCLE) { canvas_->DrawCircle(center, RADIUS, paint); } else { canvas_->DrawArc(center, RADIUS, start, end, paint); } } } void CountdownAnimatorCallback::CountingDown() { uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_; if (diffTime >= SECOND_TO_MINISECOND) { lastTime_ = HALTick::GetInstance().GetTime(); if (endAngle_ == DEGREES_PER_CIRCLE) { firstArc_ = true; } else { firstArc_ = false; } UpdatePath(0, endAngle_, true); UpdateLable(0); if (endAngle_ == 0) { stage_ = countStage::STAGE_FADE_OUT; idleTime_ = SECOND_TO_MINISECOND - CIRCLE_FADE_OUT; return; } easeDegree_ = degreePerSecond_; endAngle_ -= degreePerSecond_; if (endAngle_ <= surplusDegree) { endAngle_ = 0; easeDegree_ += surplusDegree; } updateText_ = true; } else if (diffTime + 10 >= idleTime_) { uint32_t curTime = diffTime - idleTime_; int16_t arcCurr = EasingEquation::QuadEaseInOut(0, easeDegree_, curTime, ANIMATE_TIME); UpdatePath(0, endAngle_ + easeDegree_ - arcCurr, true); UpdateLable(curTime); } } void CountdownAnimatorCallback::GradualCircle() { uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_; if (diffTime >= SECOND_TO_MINISECOND) { stage_ = countStage::STAGE_COUNTING_DOWN; idleTime_ = SECOND_TO_MINISECOND - ANIMATE_TIME; } else if (diffTime >= idleTime_) { uint32_t curTime = diffTime - idleTime_; int16_t arcCurr = EasingEquation::QuadEaseInOut(0, DEGREES_PER_CIRCLE, curTime, SECOND_TO_MINISECOND - idleTime_); } } void CountdownAnimatorCallback::SetInfo(UILabel *label, int counts) { counts_ = counts; label_ = label; } void CountdownAnimatorCallback::NotifyStart() { stage_ = countStage::STAGE_GRADUAL_CIRCLE; endAngle_ = DEGREES_PER_CIRCLE; idleTime_ = 200; // 200: idle time for first circle animate degreePerSecond_ = DEGREES_PER_CIRCLE / counts_; surplusDegree = DEGREES_PER_CIRCLE - degreePerSecond_ * counts_; label_->SetText("3"); label_->SetFont(TJD_VECTOR_FONT_FILENAME, 100); } void CountDownView::ShowView() { SportTypeIndex iconIndex = TjdUiAppSportView::currentIconIndex_; CountDownViewRefresh(iconIndex); SetVisible(true); } CountDownView::CountDownView() { static_print_info("CountDownView=======\n"); g_pv_CountDownView = this; SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); imgSport_.SetPosition(188, 0); auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_01_OUTDOOR_RUNNING, SPORT_IMAGE_BIN_PATH); imgSport_.SetSrc(imgInfo); if (canvas_ == nullptr) { canvas_ = new UICanvasExt(); } canvas_->SetPosition(0, 0, 466, 466); canvas_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); label_.SetPosition(LABEL_X, LABEL_Y, 44, 74); label_.SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); label_.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); PaintExt paint; paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); paint.SetStrokeWidth(CIRCLE_BASE_WIDTH); paint.SetAntialiased(true); paint.SetStrokeColor(Color::GetColorFromRGB(0x2d, 0x4d, 0x0a)); canvas_->DrawCircle({CENTER_X, CENTER_Y}, RADIUS, paint); callBack_ = new TJD::CountdownAnimatorCallback(canvas_); countdownAnimator_ = new Animator(callBack_, canvas_, 0, true); callBack_->SetInfo(&label_, 3); // 5: countdown numbers Add(&imgSport_); Add(canvas_); Add(&label_); } void CountDownView::HideView() { lastSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData(); countdownAnimator_->Stop(); SetVisible(false); } CountDownView::~CountDownView() { static_print_info("CountDownView==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_CountDownView = nullptr; RemoveAll(); if (canvas_ != nullptr) { delete canvas_; canvas_ = nullptr; } if (countdownAnimator_ != nullptr) { countdownAnimator_->Stop(); delete countdownAnimator_; countdownAnimator_ = nullptr; } if (callBack_ != nullptr) { delete callBack_; callBack_ = nullptr; } } CountDownView *CountDownView::GetInstance() { return g_pv_CountDownView; } void CountDownView::CountDownViewRefresh(SportTypeIndex index) { auto iconRes = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH); Vector2 scale = {0.6, 0.6}; Vector2 pivot = {30, 30}; imgSport_.SetSrc(iconRes); imgSport_.Scale(scale, pivot); imgSport_.Invalidate(); countdownAnimator_->Start(); callBack_->NotifyStart(); } #pragma region GPS定位界面 static void gpsTimerCallBack(void *arg) { static_print_info("gpsTimerCallBack\n"); static uint8_t count = 0; if (count == 180) { // �ȴ�1���� count = 0; gpsTimer_->Stop(); TjdUiAppSportModel::GetInstance()->GPSServiceClose(); } static_print_info("TjdUiAppSportModel::GetInstance()->GPSGettingLocationSuccess() = %d\n", TjdUiAppSportModel::GetInstance()->GPSGetData().valid); if (TjdUiAppSportModel::GetInstance()->GPSGetData().valid) { GraphicService::GetInstance()->PostGraphicEvent( std::bind([](void *arg) { GPSView::GetInstance()->GPSPossitionSuccessRefresh(); }, arg)); } GraphicService::GetInstance()->PostGraphicEvent( std::bind([](void *arg) { GPSView::GetInstance()->GPSViewDataRefresh(); }, arg)); count++; } bool GPSIconOnClickListener::OnClick(UIView &view, const ClickEvent &event) { static_print_info("GPSIconOnClickListener::OnClick\n"); auto sportView = TjdUiAppSportView::GetInstance(); sportView->ShowTargetView(COUNT_DOWN_VIEW); return true; } // bool GPSOnkeyActListener::OnKeyAct(OHOS::UIView &view, const OHOS::KeyEvent &event) // { // static_print_info("GPSOnkeyActListener::OnKeyAct\n"); // if (event.GetKeyId() == 4165 ) { // if (event.GetState() == OHOS::InputDevice::STATE_RELEASE) { // TjdUiAppSportView::GetInstance()->ShowTargetView(COUNT_DOWN_VIEW); // } // } // return false; // } Signal::Signal() { SetPosition(0, 0, 22, 26); signalLow_.SetPosition(0, 14, 4, 12); signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000); signalLow_.SetStyle(STYLE_BORDER_RADIUS, 2); signalMiddle_.SetPosition(9, 8, 4, 18); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000); signalMiddle_.SetStyle(STYLE_BORDER_RADIUS, 2); signalHigh_.SetPosition(18, 0, 4, 26); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0000); signalHigh_.SetStyle(STYLE_BORDER_RADIUS, 2); Add(&signalLow_); Add(&signalMiddle_); Add(&signalHigh_); } void Signal::RefreshSignal(int signal) { //先这样假定信号强度 switch (signal) { case 0 ... 2: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); break; case 3: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); break; case 4: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFea3d35); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); break; case 5 ... 15: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); break; case 16 ... 31: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFFFFFF); break; case 32 ... 999: signalLow_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); signalMiddle_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); signalHigh_.SetStyle(STYLE_BACKGROUND_COLOR, 0xff0fbd55); break; break; default: break; } signalLow_.Invalidate(); signalMiddle_.Invalidate(); signalHigh_.Invalidate(); } GPSView::GPSView(SportTypeIndex iconIndex) { static_print_info("GPSView=======\n"); g_pv_GPSView = this; SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH); UiDrawImage(&SportIcon_, 158, 156, "SportIcon_", imgInfo); const Vector2 &scale = {1.6, 1.6}; Vector2 pivot = {50, 50}; SportIcon_.Scale(scale, pivot); SportIcon_.SetStyle(STYLE_IMAGE_OPA, 76); SportIcon_.Invalidate(); SportIcon_.SetTouchable(true); SportIcon_.SetOnClickListener(&GPSIconOnClickListener_); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BATTERY_BAT_A, BATTERY_IMAGE_BIN_PATH); UiDrawImage(&imgBat_, 166, 55, imgInfo); InitLabel(batValue_, 32, 238, 48, "100%", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(GPSTitle_, 34, 30, 208, "GPS"); // imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_UNSUCCESS, SPORT_IMAGE_BIN_PATH); // UiDrawImage(&signal_, 109, 218, imgInfo); signal_.SetPosition(109, 218); signal_.RefreshSignal(0); InitLabel(hrValue_, 32, 350, 236, "--", TJD_DIN_MEDIUM_FONT_FILENAME); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_HR, SPORT_IMAGE_BIN_PATH); UiDrawImage(&hrIcon_, 350, 184, imgInfo); // InitLabelHorCenter(GPSTip_, 34, 312, 466, "定位中..."); GPSTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); GPSTip_.SetTextId(STR_ID_190); GPSTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE); GPSTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); GPSTip_.SetPosition(0, 312, 466, 46); // InitLabelHorCenter(GPSTip1_, 30, 367, 466, "请到空旷位置等待"); GPSTip1_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); GPSTip1_.SetTextId(STR_ID_191); GPSTip1_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP); GPSTip1_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); GPSTip1_.SetPosition(60, 367, 346, 46); GPSTip1_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); if (gpsTimer_ == nullptr) { gpsTimer_ = new OHOS::GraphicTimer(1000, gpsTimerCallBack, nullptr, true); } Add(&GPSTip_); Add(&GPSTip1_); Add(&GPSTitle_); Add(&SportIcon_); Add(&signal_); Add(&hrIcon_); Add(&hrValue_); Add(&imgBat_); Add(&batValue_); } void GPSView::ShowView() { auto model = TjdUiAppSportModel::GetInstance(); if (model == nullptr) return; signal_.RefreshSignal(0); model->RegisterGnssChangedCB(); set_back_to_home_interval(60 * 3); // 运动进行中熄屏不允许返回主表盘 model->GPSServiceOpen(); model->SportHeartRateControlHandler(SportingAction::Start, nullptr); SportTypeIndex iconIndex = TjdUiAppSportView::currentIconIndex_; GPSViewRefresh(iconIndex); GPSViewDataRefresh(); if (gpsTimer_ != nullptr) gpsTimer_->Start(); SetVisible(true); } void GPSView::HideView() { auto model = TjdUiAppSportModel::GetInstance(); if (model == nullptr) return; model->UnregisterGnssChangedCB(); set_back_to_home_interval(5); if (!model->GPSGetData().valid) model->GPSServiceClose(); if (gpsTimer_ != nullptr) gpsTimer_->Stop(); SetVisible(false); } GPSView *GPSView::GetInstance() { return g_pv_GPSView; } GPSView::~GPSView() { static_print_info("GPSView==line[%d]==func[%s]\n", __LINE__, __func__); g_pv_GPSView = nullptr; if (gpsTimer_ != nullptr) { gpsTimer_->Stop(); delete gpsTimer_; gpsTimer_ = nullptr; } RemoveAll(); } void GPSView::GPSViewRefresh(SportTypeIndex index) { auto iconRes = OHOS::ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH); Vector2 scale = {1.6, 1.6}; Vector2 pivot = {50, 50}; SportIcon_.SetSrc(iconRes); SportIcon_.SetX(183); SportIcon_.Scale(scale, pivot); SportIcon_.SetStyle(STYLE_IMAGE_OPA, 76); SportIcon_.Invalidate(); } void GPSView::GPSViewDataRefresh(void) { auto model = TjdUiAppSportModel::GetInstance(); if (model == nullptr) return; if (model->GetCurHeartRateValue()) { hrValue_.SetText(std::to_string(model->GetCurHeartRateValue()).c_str()); } else hrValue_.SetText("--"); uint8_t battery = model->GetBatteryValue(); uint8_t bat_level = battery / 10; signal_.RefreshSignal(model->GetMaxSnr()); auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BATTERY_BAT_0 + bat_level, BATTERY_IMAGE_BIN_PATH); imgBat_.SetSrc(imgInfo); batValue_.SetText((std::to_string(model->GetBatteryValue()) + std::string("%")).c_str()); } void GPSView::GPSPossitionSuccessRefresh() { static_print_info("GPSPossitionSuccessRefresh\n"); SportIcon_.SetStyle(STYLE_IMAGE_OPA, 255); SportIcon_.Invalidate(); // InitLabelHorCenter(GPSTip_, 34, 312, 466, "定位成功"); GPSTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); GPSTip_.SetTextId(STR_ID_192); GPSTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE); GPSTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); GPSTip_.SetPosition(0, 312, 466, 46); // InitLabelHorCenter(GPSTip1_, 30, 367, 466, "点击右上按键开始"); GPSTip1_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); GPSTip1_.SetTextId(STR_ID_192); GPSTip1_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE); GPSTip1_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); GPSTip1_.SetPosition(60, 367, 346, 46); GPSTip1_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); // auto imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_GPS_SUCCESS, BATTERY_IMAGE_BIN_PATH); // signal_.SetSrc(imgInfo); } #pragma endregion #pragma region 运动进行中 ImgEndOnTouchListener::ImgEndOnTouchListener() { pressImgSrc_ = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_PRESS, SPORT_IMAGE_BIN_PATH); releaseImgSrc_ = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH); } ImgEndOnTouchListener::~ImgEndOnTouchListener() { static_print_info("ImgEndOnTouchListener::Destory..."); if (pressImgSrc_ != nullptr) { pressImgSrc_ = nullptr; } if (releaseImgSrc_ != nullptr) { releaseImgSrc_ = nullptr; } }; bool ImgEndOnTouchListener::OnPress(UIView &view, const PressEvent &event) { SportingView::GetInstance()->imgEnd_.SetSrc(pressImgSrc_); view.SetDragParentInstead(false); if (SportingView::GetInstance()->animator_->GetState() == Animator::STOP) SportingView::GetInstance()->animator_->Start(); return true; } bool ImgEndOnTouchListener::OnRelease(UIView &view, const ReleaseEvent &event) { auto sportingView = SportingView::GetInstance(); sportingView->imgEnd_.SetSrc(releaseImgSrc_); SportingView::GetInstance()->animator_->Stop(); return true; } bool ImgEndOnTouchListener::OnCancel(OHOS::UIView &view, const OHOS::CancelEvent &event) { auto sportingView = SportingView::GetInstance(); sportingView->imgEnd_.SetSrc(releaseImgSrc_); SportingView::GetInstance()->animator_->Stop(); return true; } ///********************************************************************************************************************/ /// @brief :运动进行中主界面 ///********************************************************************************************************************/ static char *str = nullptr; static void TimerCallBack(void *arg) { static_print_info("TimerCallBack\n"); int curTime = HALTick::GetInstance().GetTime(); if (curTime - SportingView::lastTime >= 1000) { GraphicService::GetInstance()->PostGraphicEvent(std::bind( [](void *arg) { if (timerCount == 0) // 60//临时调试 { if (TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath().size() <= 14) { str = (char *)TjdUiAppSportModel::GetInstance() ->RecordSportData(); // 当时间到达60秒时,记录一次运动数据 } else { std::vector fileList = TjdUiAppSportModel::GetInstance()->SearchAndRecordFilepath(); // 如果 fileList 达到最大数量,删除最旧的文件 if (fileList.size() >= 15) { TjdUiAppSportModel::GetInstance()->RemoveFile((const char *)fileList[0].c_str()); fileList.erase(fileList.begin()); // 删除第一个元素 } str = (char *)TjdUiAppSportModel::GetInstance() ->RecordSportData(); // 当时间到达60秒时,记录一次运动数据 // 添加新的文件名 static_print_info("new file name = %s\n", str); fileList.push_back(str); } } if (timerCount > 0 && timerCount % 1 == 0) { // 临时调试 gnss_data_t gps_data = TjdUiAppSportModel::GetInstance()->GPSGetData(); TjdUiAppSportModel::GetInstance()->AddDataToArry(str, gps_data.latitude, gps_data.longitude); TjdUiAppSportModel::GetInstance()->UpdateSportData(str); // TjdUiAppSportModel::GetInstance()->RenameSportDataFile(str); } else if (timerCount > 0) { TjdUiAppSportModel::GetInstance()->UpdateSportData(str); } pthread_mutex_lock(&data_mutex); SportingData_t curSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData(); pthread_mutex_unlock(&data_mutex); SportingView::GetInstance()->SportingViewDateRefresh(curSportingData); timerCount++; }, arg)); SportingView::lastTime = HALTick::GetInstance().GetTime(); } } SportingView::SportingView() { static_print_info("SportingMainView::SportingMainView"); g_pv_SportingView = this; SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_; // if (swipeGPSView_ == nullptr) { // swipeGPSView_ = new UISwipeView(OHOS::UISwipeView::VERTICAL); // } // swipeGPSView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); // swipeGPSView_->SetDragParentInstead(false); // swipeGPSView_->SetOnSwipeListener(onSwipeListener_); // swipeGPSView_->SetOnDragListener(OnDragListener_); // swipeGPSView_->SetOnClickListener(onClickListener_); // if (containerView_ == nullptr) { // containerView_ = new UIViewGroup(); // } // containerView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); if (swipeMainView_ == nullptr) { swipeMainView_ = new UISwipeView(OHOS::UISwipeView::HORIZONTAL); } swipeMainView_->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); // swipeMainView_->SetOnSwipeListener(onSwipeListener_); swipeMainView_->SetOnDragListener(OnDragListener_); swipeMainView_->SetOnClickListener(onClickListener_); #if 0 // swipeMainView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_)); // containerView_->Add(swipeGPSView_); swipeMainView_->Add(InitSportingGPSView(&sportingGPSView_)); swipeMainView_->Add(swipeGPSView_); swipeGPSView_->Add(InitsportingDataRecordView(&sportingDataRecordView_, iconIndex)); // swipeGPSView_->Add(InitSportingGPSView(&sportingGPSView_)); swipeGPSView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_)); #else swipeMainView_->Add(InitSportingPauseOrContinueView(&sportingPauseOrContinueView_)); swipeMainView_->Add(InitsportingDataRecordView(&sportingDataRecordView_, iconIndex)); InitSportingGPSView(&sportingGPSView_); #endif // swipeGPSView_->SetOnSwipeListener(onSwipeListener_); if (sportingTimer_ == nullptr) { sportingTimer_ = new OHOS::GraphicTimer(250, TimerCallBack, nullptr, true); } Add(swipeMainView_); } static uint8_t gpsTrack = 0; void SportingView::ShowView() { static_print_info("tjd_get_service_if_open = %d\n", tjd_get_service_if_open()); timerCount = 0; g_comeback_dial_interval = get_back_to_home_interval(); set_back_to_home_interval(0xFFFFFFFF); // 运动进行中熄屏不允许返回主表盘 TjdUiAppSportModel::GetInstance()->SetSportEndRemindType(SPORT_MSG_TYPE_END_30_MIN_REMIND); UIView *view = swipeMainView_->GetChildById("sportingGPSView"); if (static_cast(view)) { printf("view is not null\n"); if (SportingView::sportType == SPORT_TYPE_1 || SportingView::sportType == SPORT_TYPE_2) ShowGPSTrackView(true); else HideGPSTrackView(); } else { printf("view is null\n"); if (SportingView::sportType == SPORT_TYPE_1 || SportingView::sportType == SPORT_TYPE_2) ShowGPSTrackView(false); } ResetSwipeView(); if (!TjdUiAppSportModel::GetInstance()->GPSGetData().valid) //运动开始时,如果gps数据无效,则关闭gps服务 { printf("gps data invalid, close gps service\n"); // TjdUiAppSportModel::GetInstance()->GPSServiceClose(); TjdUiAppSportView::GetInstance()->SetGPState(false); } else TjdUiAppSportView::GetInstance()->SetGPState(true); if (!tjd_get_service_if_open()) { tjd_service_sport_open(); } if (returnToDial) { sportingTimer_->Start(); } SportingViewRefresh(); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH); imgEnd_.SetSrc(imgInfo); SetVisible(true); } void SportingView::HideView() { static_print_info("SportingMainView::HideView\n"); set_back_to_home_interval(g_comeback_dial_interval); if (tjd_get_service_if_open()) { tjd_service_sport_close(); } sportingTimer_->Stop(); SetPauseOrContinueCheckBoxState(1); if (!returnToDial) //如果回到主表盘,则不关闭GPS、心率 { auto model = TjdUiAppSportModel::GetInstance(); if (model == nullptr) return; model->GPSServiceClose(); // 关闭GPS服务 model->SportHeartRateControlHandler(SportingAction::Stop, nullptr); } SetVisible(false); } void SportingView::ShowGPSTrackView(bool exit) { gpsTrack = 0; //轨迹假数据 if (!exit) swipeMainView_->Add(sportingGPSView_); gpsCanvas_.Clear(); trajectory.clear(); gpsTrackTimer_->Start(); GPS_CAVAS_WIDTH = 214; GPS_CAVAS_HEIGHT = 252; gpsCanvas_.SetPosition(126, 107, GPS_CAVAS_WIDTH, GPS_CAVAS_HEIGHT); if (TjdUiAppSportModel::GetInstance()->GPSGetData().valid) lbState_.SetTextId(STR_ID_195); else lbState_.SetTextId(STR_ID_194); } void SportingView::HideGPSTrackView() { printf("HideGPSTrackView\n"); swipeMainView_->Remove(sportingGPSView_); gpsTrackTimer_->Stop(); } SportingView::~SportingView() { static_print_info("SportingMainView Destory=======\n"); RemoveAll(); if (!returnToDial) //如果回到主表盘,则不关闭GPS、心率 { auto model = TjdUiAppSportModel::GetInstance(); if (model == nullptr) return; model->GPSServiceClose(); // 关闭GPS服务 model->SportHeartRateControlHandler(SportingAction::Stop, nullptr); } if (stopAnimatorCallback_ != nullptr) { delete stopAnimatorCallback_; stopAnimatorCallback_ = nullptr; } if (animator_ != nullptr) { animator_->Stop(); delete animator_; animator_ = nullptr; } if (gpsTrackTimer_ != nullptr) { gpsTrackTimer_->Stop(); delete gpsTrackTimer_; gpsTrackTimer_ = nullptr; } if (trackAnimator_ != nullptr) { trackAnimator_->Stop(); delete trackAnimator_; trackAnimator_ = nullptr; } if (swipeMainView_ != nullptr) { swipeMainView_->Remove(sportingDataRecordView_); swipeMainView_->Remove(sportingPauseOrContinueView_); swipeMainView_->Remove(sportingGPSView_); delete swipeMainView_; swipeMainView_ = nullptr; } if (imgEndOnTouchListener_ != nullptr) { delete imgEndOnTouchListener_; imgEndOnTouchListener_ = nullptr; } if (sportViewOnClickedListener_ != nullptr) { delete sportViewOnClickedListener_; sportViewOnClickedListener_ = nullptr; } if (sportingGPSView_) { sportingGPSView_->RemoveAll(); delete sportingGPSView_; sportingGPSView_ = nullptr; } if (sportingPauseOrContinueView_) { sportingPauseOrContinueView_->RemoveAll(); delete sportingPauseOrContinueView_; sportingPauseOrContinueView_ = nullptr; } if (sportingDataRecordView_) { sportingDataRecordView_->RemoveAll(); delete sportingDataRecordView_; sportingDataRecordView_ = nullptr; } if (sportingTimer_ != nullptr) { sportingTimer_->Stop(); delete sportingTimer_; sportingTimer_ = nullptr; } // if (onSwipeListener_ != nullptr) { // delete onSwipeListener_; // onSwipeListener_ = nullptr; // } // if (OnDragListener_ != nullptr) { // delete OnDragListener_; // OnDragListener_ = nullptr; // } if (onClickListener_ != nullptr) { delete onClickListener_; onClickListener_ = nullptr; } g_pv_SportingView = nullptr; } void SportingView::SportingViewDateRefresh(SportingData_t curSportingData) { auto sportView = TjdUiAppSportView::GetInstance(); auto lastSportingData_ = lastSportingData; std::ostringstream sportTimeOss; std::ostringstream oss; std::ostringstream caloriesOss; std::ostringstream distanceOss; static_print_info("===curSportingData.distance=%d ==lastSportingData.distance%d===\n", curSportingData.distance, lastSportingData_.distance); // Time currentTime = sportView->GetCurrentTime(GetSportingRtcLabelText()); hours = curSportingData.exerciseDuration / 3600; minutes = (curSportingData.exerciseDuration % 3600) / 60; seconds = curSportingData.exerciseDuration % 60; sportTimeOss << std::setw(2) << std::setfill('0') << hours << ":" << std::setw(2) << std::setfill('0') << minutes << ":" << std::setw(2) << std::setfill('0') << seconds; SetSportingRtcLabelText(sportTimeOss.str().c_str()); if (curSportingData.heartRate) heartRateLabel_.SetText(std::to_string(curSportingData.heartRate).c_str()); else heartRateLabel_.SetText("---"); distance = curSportingData.distance/1000.0f; calories = curSportingData.calories; step = curSportingData.steps; switch (curSportingData.heartRate) { case 40 ... 138: imgPoint_.Rotate(240, VIEW_CENTER); break; case 139 ... 150: imgPoint_.Rotate(300, VIEW_CENTER); break; case 151 ... 162: imgPoint_.Rotate(0, VIEW_CENTER); break; case 163 ... 174: imgPoint_.Rotate(60, VIEW_CENTER); break; case 175 ... 200: imgPoint_.Rotate(120, VIEW_CENTER); break; default: imgPoint_.Rotate(0, VIEW_CENTER); break; } oss << std::setw(5) << std::setfill('0') << step; stepLabel_.SetText(oss.str().c_str()); caloriesOss << std::setw(4) << std::setfill('0') << calories; caloriesLabel_.SetText(caloriesOss.str().c_str()); distanceOss << std::fixed << std::setprecision(2) << distance; // 设置固定小数点格式和一位小数 distanceLabel_.SetText(distanceOss.str().c_str()); static_print_info("===sportTimeOss=%s==%s=%s=%s=\n", sportTimeOss.str().c_str(), oss.str().c_str(), caloriesOss.str().c_str(), distanceOss.str().c_str()); } SportingView *SportingView::GetInstance() { return g_pv_SportingView; } ///********************************************************************************************************************/ /// @brief :运动进行中数据记录界面 ///********************************************************************************************************************/ OHOS::UIViewGroup *SportingView::InitsportingDataRecordView(OHOS::UIViewGroup **sportingDataRecordView_, SportTypeIndex index) { if (*sportingDataRecordView_ == nullptr) { *sportingDataRecordView_ = new UIViewGroup(); } (*sportingDataRecordView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[index].imgIconResId, SPORT_IMAGE_BIN_PATH); UIDrawImageScale(&imgSportIcon_, 193, 40, imgInfo, 0.6, 0.6, 30, 30); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_01, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHr01, 0, 225, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_02, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHr02, 0, 29, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_03, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHr03, 113, 0, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_04, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHr04, 339, 30, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR_05, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHr05, 338, 225, imgInfo); InitLabelHorCenter(sportingRtcLabel_, 72, 301, OHOS::HORIZONTAL_RESOLUTION, "00:00:00", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(stepLabel_, 50, 170, 203, "00000", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(caloriesLabel_, 50, 333, 203, "0000", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(heartRateLabel_, 50, 197, 122, "---", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(distanceLabel_, 50, 45, 203, "0.00", TJD_DIN_MEDIUM_FONT_FILENAME); // InitLabel(stepUnitLabel_, 30, 222, 258, "步"); stepUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); stepUnitLabel_.SetTextId(STR_ID_547); stepUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); stepUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); stepUnitLabel_.SetPosition(222, 258); stepUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_SPORTING_KCAL, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgCaloriesIcon_, 126, 219, imgInfo); // InitLabel(caloriesUnitLabel_, 30, 349, 258, "千卡"); caloriesUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); caloriesUnitLabel_.SetTextId(STR_ID_576); caloriesUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); caloriesUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); caloriesUnitLabel_.SetPosition(349, 258); caloriesUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); // InitLabelHorCenter(sportingTimeLabel_, 30, 378, OHOS::HORIZONTAL_RESOLUTION, "时间"); sportingTimeLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); sportingTimeLabel_.SetTextId(STR_ID_594); // sportingTimeLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); sportingTimeLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); sportingTimeLabel_.SetPosition(0, 378, 466, 42); sportingTimeLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); OHOS::UIImageView *imgHrIcon = new UIImageView(); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_HR, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgHrIcon_, 130, 143, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_TRIANGLE, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgPoint_, 0, 0, imgInfo); // imgPoint_.Rotate(10, VIEW_CENTER); // imgPoint_.Invalidate(); // InitLabel(heartRateUnitLabel_, 30, , 140, "次/分"); heartRateUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); heartRateUnitLabel_.SetTextId(STR_ID_110); heartRateUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); heartRateUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); heartRateUnitLabel_.SetPosition(276, 140); heartRateUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); // InitLabel(distanceUnitLabel_, 30, 57, 258, "千米"); distanceUnitLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); distanceUnitLabel_.SetTextId(STR_ID_632); distanceUnitLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); distanceUnitLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); distanceUnitLabel_.SetPosition(57, 258); distanceUnitLabel_.SetStyle(STYLE_TEXT_OPA, 0xff * 0.3); sportingPage.SetPosition(205, 422); sportingPage.Resize(16, 16); sportingPage.SetStyle(STYLE_BACKGROUND_COLOR, 0xff262626); sportingPage.SetStyle(STYLE_BORDER_RADIUS, 16); lastPage.SetPosition(245, 422); lastPage.Resize(16, 16); lastPage.SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff); lastPage.SetStyle(STYLE_BORDER_RADIUS, 16); firstInterval.SetPosition(144, 199); firstInterval.Resize(2, 98); firstInterval.SetStyle(STYLE_BACKGROUND_COLOR, 0xFF646464); secondInterval.SetPosition(316, 199); secondInterval.Resize(2, 98); secondInterval.SetStyle(STYLE_BACKGROUND_COLOR, 0xFF646464); (*sportingDataRecordView_)->Add(&imgSportIcon_); (*sportingDataRecordView_)->Add(&imgHr01); (*sportingDataRecordView_)->Add(&imgHr02); (*sportingDataRecordView_)->Add(&imgHr03); (*sportingDataRecordView_)->Add(&imgHr04); (*sportingDataRecordView_)->Add(&imgHr05); (*sportingDataRecordView_)->Add(&imgHrIcon_); (*sportingDataRecordView_)->Add(&imgPoint_); (*sportingDataRecordView_)->Add(&sportingRtcLabel_); (*sportingDataRecordView_)->Add(&stepLabel_); (*sportingDataRecordView_)->Add(&stepUnitLabel_); (*sportingDataRecordView_)->Add(&caloriesLabel_); (*sportingDataRecordView_)->Add(&caloriesUnitLabel_); (*sportingDataRecordView_)->Add(&heartRateLabel_); (*sportingDataRecordView_)->Add(&heartRateUnitLabel_); (*sportingDataRecordView_)->Add(&distanceLabel_); (*sportingDataRecordView_)->Add(&distanceUnitLabel_); (*sportingDataRecordView_)->Add(&sportingPage); (*sportingDataRecordView_)->Add(&lastPage); (*sportingDataRecordView_)->Add(&firstInterval); (*sportingDataRecordView_)->Add(&secondInterval); (*sportingDataRecordView_)->Add(&sportingTimeLabel_); (*sportingDataRecordView_)->Add(&imgCaloriesIcon_); return (*sportingDataRecordView_); } void SportingView::SportingViewRefresh() { static_print_info("lines = %d ,func = %s\n", __LINE__, __FUNCTION__); auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_; // TjdUiAppSportPresenter::GetInstance()->SetCurrentSportingData(); switch (iconIndex) { case SPORT_TYPE_01_OUTDOOR_RUNNING_INDEX: case SPORT_TYPE_02_OUTDOOR_WALKING_INDEX: case SPORT_TYPE_04_FOOTBALL_INDEX: case SPORT_TYPE_05_BASKETBALL_INDEX: case SPORT_TYPE_12_ON_FOOT_INDEX: case SPORT_TYPE_13_STAIRCASE_INDEX: stepLabel_.SetPosition(170, 203); stepLabel_.SetVisible(true); stepUnitLabel_.SetPosition(222, 258); stepUnitLabel_.SetVisible(true); caloriesLabel_.SetPosition(333, 203); caloriesUnitLabel_.SetPosition(349, 258); distanceLabel_.SetPosition(45, 203); distanceLabel_.SetVisible(true); distanceUnitLabel_.SetPosition(57, 258); distanceUnitLabel_.SetVisible(true); firstInterval.SetVisible(true); secondInterval.SetVisible(true); firstInterval.SetPosition(144, 199); secondInterval.SetPosition(316, 199); imgCaloriesIcon_.SetVisible(false); break; case SPORT_TYPE_09_INDOOR_SWIMMI_INDEX: case SPORT_TYPE_10_OUTDOOR_SWIMM_INDEX: case SPORT_TYPE_11_CYCLING_INDEX: case SPORT_TYPE_51_RIDING_INDEX ... SPORT_TYPE_57_MOTORBOAT_INDEX: stepLabel_.SetVisible(false); stepUnitLabel_.SetVisible(false); caloriesLabel_.SetPosition(278, 203); caloriesUnitLabel_.SetPosition(299, 258); distanceLabel_.SetPosition(101, 203); distanceLabel_.SetVisible(true); distanceUnitLabel_.SetPosition(115, 258); distanceUnitLabel_.SetVisible(true); firstInterval.SetVisible(true); firstInterval.SetPosition(232, 199); secondInterval.SetVisible(false); imgCaloriesIcon_.SetVisible(false); break; default: stepLabel_.SetVisible(false); stepUnitLabel_.SetVisible(false); caloriesLabel_.SetPosition(197, 212); caloriesUnitLabel_.SetPosition(314, 230); distanceLabel_.SetVisible(false); distanceUnitLabel_.SetVisible(false); firstInterval.SetVisible(false); secondInterval.SetVisible(false); imgCaloriesIcon_.SetVisible(true); break; } if (returnToDial) { SportingData_t curSportingData = TjdUiAppSportModel::GetInstance()->GetServiceSportData(); // 读取数据 char recoverDate[10] = {0}; uint32_t hours = curSportingData.exerciseDuration / 3600; uint32_t minutes = (curSportingData.exerciseDuration % 3600) / 60; uint32_t seconds = curSportingData.exerciseDuration % 60; sprintf(recoverDate, "%02d:%02d:%02d", hours, minutes, seconds); sportingRtcLabel_.SetText(recoverDate); memset(recoverDate, 0, sizeof(recoverDate)); sprintf(recoverDate, "%05d", curSportingData.steps); stepLabel_.SetText(recoverDate); memset(recoverDate, 0, sizeof(recoverDate)); sprintf(recoverDate, "%04d", curSportingData.calories); caloriesLabel_.SetText(recoverDate); memset(recoverDate, 0, sizeof(recoverDate)); if (curSportingData.heartRate) sprintf(recoverDate, "%d", curSportingData.heartRate); else sprintf(recoverDate, "---"); heartRateLabel_.SetText(recoverDate); memset(recoverDate, 0, sizeof(recoverDate)); sprintf(recoverDate, "%.2f", curSportingData.distance / 1000.0f); distanceLabel_.SetText(recoverDate); } else { sportingRtcLabel_.SetText("00:00:00"); stepLabel_.SetText("00000"); caloriesLabel_.SetText("0000"); distanceLabel_.SetText("0.00"); heartRateLabel_.SetText("---"); } ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH); imgSportIcon_.SetSrc(imgInfo); imgSportIcon_.Invalidate(); } ///********************************************************************************************************************/ /// @brief :运动进行中暂停或继续界面 ///********************************************************************************************************************/ void StopAnimatorCallback::Callback(OHOS::UIView *view) { if (animator_ == nullptr || canvas_ == nullptr) { return; } canvas_->Clear(); OHOS::Point center = {233, 233}; OHOS::ColorType color; color.full = 0xFF660e16; paint_.SetStrokeColor(color); canvas_->DrawArc(center, 223, 360, 0, paint_); color.full = 0xFFFE2337; paint_.SetStrokeColor(color); int16_t value = OHOS::EasingEquation::LinearEaseNone(0, 359, animator_->GetRunTime(), animator_->GetTime()); canvas_->DrawArc(center, 223, 360, value, paint_); if (animator_->GetRunTime() >= animator_->GetTime()) { animator_->Stop(); auto sportView = TjdUiAppSportView::GetInstance(); auto sportingView = SportingView::GetInstance(); Time currentTime = sportView->GetCurrentTime(sportingView->GetSportingRtcLabelText()); sportingView->SetSwipeViewDraggable(true); sportingView->ResetSwipeView(); // sportingView->SetSportingRtcLabelText("00:00:00"); sportingView->SetPauseOrContinueCheckBoxState(1); switch (SportingView::sportType) { case SPORT_TYPE_1: printf("SportType = %d, Step = %d\n", SportingView::sportType, SportingView::GetInstance()->GetStep()); if (SportingView::GetInstance()->GetStep() < 100) { // 1分钟后开始记录数据(临时调试) sportView->ShowTargetView(SPORT_END_NODATA_VIEW); } else { sportView->ShowTargetView(SPORT_END_DATA_VIEW); } break; case SPORT_TYPE_2: case SPORT_TYPE_3: if (currentTime.minutes < 1) { // 1分钟后开始记录数据(临时调试) sportView->ShowTargetView(SPORT_END_NODATA_VIEW); } else { sportView->ShowTargetView(SPORT_END_DATA_VIEW); } break; } } } void StopAnimatorCallback::OnStop(OHOS::UIView &view) { canvas_->Clear(); } std::vector NewTrajectory = { {22.578361511230469f, 113.90731811523438f}, {22.578344345092773f, 113.90730285644531f}, {22.578323364257812f, 113.90728759765625f}, {22.578306198120117f, 113.90727233886719f}, {22.578290939331055f, 113.90725708007812f}, {22.57826042175293f, 113.90724182128906f}, {22.5782299041748f, 113.9072265625f}, {22.578201293945312f, 113.90721130371094f}, {22.578180313110352f, 113.9072265625f}, {22.578153610229492f, 113.90725708007812f}, {22.578121185302734f, 113.90727996826172f}, {22.578102111816406f, 113.90729522705078f}, {22.57807731628418f, 113.90732574462891f}, {22.578042984008789f, 113.90735626220703f}, {22.578006744384766f, 113.90739440917969f}, {22.577968597412109f, 113.90742492675781f}, {22.577959060668945f, 113.90745544433594f}, {22.578006744384766f, 113.90748596191406f}, {22.578046798706055f, 113.90750885009766f}, {22.578084945678711f, 113.90747833251953f}, {22.5781192779541f, 113.90743255615234f}, {22.578145980834961f, 113.90738677978516f}, {22.57819938659668f, 113.90732574462891f}, {22.578237533569336f, 113.90727996826172f}, {22.578277587890625f, 113.90724182128906f}, {22.578315734863281f, 113.90721893310547f}, {22.57832145690918f, 113.9072265625f}, {22.578342437744141f, 113.90726470947266f}, {22.578371047973633f, 113.90730285644531f}, {22.578403472900391f, 113.90734100341797f}, {22.578405380249023f, 113.90737915039062f}, {22.578407287597656f, 113.90738677978516f}}; static void gpsTrackTimerCallBack(void *arg) { GraphicService::GetInstance()->PostGraphicEvent(std::bind( [](void *arg) { OHOS::UICanvas *canvas_ = static_cast(arg); if (canvas_ == nullptr) return; auto sportingView = SportingView::GetInstance(); if (sportingView == nullptr) return; std::vector &trajectory = sportingView->GetTrajectory(); sportingView->UpdateGPSTrack(canvas_, trajectory); if (gpsTrack < NewTrajectory.size() - 1) gpsTrack++; }, arg)); } void SportingView::GPSCanvasAutoCenter() { gpsCanvas_.SetPosition((466 - GPS_CAVAS_WIDTH) / 2, (466 - GPS_CAVAS_HEIGHT) / 2, GPS_CAVAS_WIDTH, GPS_CAVAS_HEIGHT); UpdateGPSTrack(&gpsCanvas_, trajectory); Invalidate(); } void SportingView::UpdateGPSTrack(OHOS::UICanvas *canvas, std::vector &trajectory) { canvas->Clear(); Paint paint; paint.SetStrokeColor(Color::Green()); paint.SetStrokeWidth(2); paint.SetOpacity(OPA_OPAQUE); gnss_data_t gps_data = TjdUiAppSportModel::GetInstance()->GPSGetData(); Coordinate centerPoint; centerPoint.latitude = gps_data.latitude; centerPoint.longitude = gps_data.longitude; // centerPoint = NewTrajectory[gpsTrack]; trajectory.push_back(centerPoint); // 计算动态比例尺(根据最大偏移量自动缩放) double maxLatOffset = 0; double maxLonOffset = 0; for (const auto &coord : trajectory) { // printf("(coord.latitude%.15f,coord.longitude %.15f)\n", coord.latitude, coord.longitude); double latOffset = std::abs(coord.latitude - centerPoint.latitude); double lonOffset = std::abs(coord.longitude - centerPoint.longitude); if (latOffset > maxLatOffset) maxLatOffset = latOffset; if (lonOffset > maxLonOffset) maxLonOffset = lonOffset; } // printf("line = %d================\n", __LINE__); // 防止除零 const double epsilon = 1e-9; maxLatOffset = std::max(maxLatOffset, epsilon); maxLonOffset = std::max(maxLonOffset, epsilon); // 计算每度对应的像素数(取安全比例的80%) const double latScale = (GPS_CAVAS_HEIGHT / 2.0 * 0.8) / maxLatOffset; const double lonScale = (GPS_CAVAS_WIDTH / 2.0 * 0.8) / maxLonOffset; const double scale = std::min(latScale, lonScale); // printf("line = %d================\n", __LINE__); bool isFirst = true; Point prevPosition; for (const auto &point : trajectory) { // 计算相对中心点的偏移量 double latOffset = point.latitude - centerPoint.latitude; double lonOffset = point.longitude - centerPoint.longitude; // 转换为屏幕坐标(中心点为屏幕中心) int x = static_cast(GPS_CAVAS_WIDTH / 2 + lonOffset * scale); int y = static_cast(GPS_CAVAS_HEIGHT / 2 - latOffset * scale); // Y轴翻转 // 边界保护 x = std::max(0, std::min(x, GPS_CAVAS_WIDTH - 1)); y = std::max(0, std::min(y, GPS_CAVAS_HEIGHT - 1)); Point position{x, y}; // static_print_info("Screen: (%d, %d)\n", position.x, position.y); if (isFirst) { Paint centerPaint; centerPaint.SetStrokeColor(Color::Green()); centerPaint.SetStrokeWidth(4); canvas->DrawCircle(position, 2, centerPaint); // 中心点画红色圆点 canvas->SetStartPosition(position); isFirst = false; } else { canvas->DrawLine(position, paint); prevPosition = position; } } } OHOS::UIViewGroup *SportingView::InitSportingGPSView(OHOS::UIViewGroup **sportingGPSView_) { static_print_info("TjdUiAppSportView::InitSportingGPSViewInit..."); if (*sportingGPSView_ == nullptr) { *sportingGPSView_ = new UIViewGroup(); } (*sportingGPSView_)->SetViewId("sportingGPSView"); (*sportingGPSView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); (*sportingGPSView_)->SetViewIndex(0); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_SHRINK, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgShrink_, 22, 194, imgInfo); imgShrink_.SetTouchable(true); imgShrink_.SetViewId("imgShrink"); imgShrink_.SetOnClickListener(&GPSTrackListener_); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_ENLARGE, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgEnlarge_, 376, 194, imgInfo); imgEnlarge_.SetTouchable(true); imgEnlarge_.SetViewId("imgEnlarge_"); imgEnlarge_.SetOnClickListener(&GPSTrackListener_); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_BJ_GPS, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgState_, 77, 378, imgInfo); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_DESTINATION, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgDestination_, 222, 218, imgInfo); gpsCanvas_.SetPosition(126, 107, GPS_CAVAS_WIDTH, GPS_CAVAS_HEIGHT); // trackAnimator_->Start(); lbState_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); lbState_.SetTextId(STR_ID_194); lbState_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); lbState_.SetPosition(0, 400, 466, 47); if (gpsTrackTimer_ == nullptr) { gpsTrackTimer_ = new OHOS::GraphicTimer(1000, gpsTrackTimerCallBack, (void *)&gpsCanvas_, true); } (*sportingGPSView_)->Add(&gpsCanvas_); (*sportingGPSView_)->Add(&imgShrink_); (*sportingGPSView_)->Add(&imgEnlarge_); (*sportingGPSView_)->Add(&imgState_); (*sportingGPSView_)->Add(&imgDestination_); (*sportingGPSView_)->Add(&lbState_); return (*sportingGPSView_); } OHOS::UIViewGroup *SportingView::InitSportingPauseOrContinueView(OHOS::UIViewGroup **sportingPauseOrContinueView_) { static_print_info("TjdUiAppSportView::PauseOrContinueDuringSportingViewInit..."); if (*sportingPauseOrContinueView_ == nullptr) { *sportingPauseOrContinueView_ = new UIViewGroup(); } (*sportingPauseOrContinueView_)->SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); (*sportingPauseOrContinueView_)->SetViewIndex(0); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_RELEASE, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgEnd_, 54, 168, imgInfo); imgEnd_.SetTouchable(true); if (imgEndOnTouchListener_ == nullptr) imgEndOnTouchListener_ = new ImgEndOnTouchListener(); imgEnd_.SetOnTouchListener(imgEndOnTouchListener_); auto selectedImg = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_KEEP, SPORT_IMAGE_BIN_PATH); auto unselectedImg = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_PAUSE, SPORT_IMAGE_BIN_PATH); pauseOrContinueCheckBox_.SetPosition(282, 168, 130, 130); pauseOrContinueCheckBox_.SetState(UICheckBox::UNSELECTED); pauseOrContinueCheckBox_.SetImages(selectedImg, unselectedImg); pauseOrContinueCheckBox_.SetViewId("pauseOrContinueCheckBox_"); if (sportViewOnClickedListener_ == nullptr) sportViewOnClickedListener_ = new SportViewOnClickedListener(); pauseOrContinueCheckBox_.SetOnClickListener(sportViewOnClickedListener_); canvas_.SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); stopAnimatorCallback_ = new StopAnimatorCallback(&canvas_); animator_ = new OHOS::Animator(stopAnimatorCallback_, nullptr, 3000, true); stopAnimatorCallback_->SetAnimator(animator_); prePage.SetPosition(245, 422); prePage.Resize(16, 16); prePage.SetStyle(STYLE_BACKGROUND_COLOR, 0xff262626); prePage.SetStyle(STYLE_BORDER_RADIUS, 16); PauseOrContinuePage.SetPosition(205, 422); PauseOrContinuePage.Resize(16, 16); PauseOrContinuePage.SetStyle(STYLE_BACKGROUND_COLOR, 0xffffffff); PauseOrContinuePage.SetStyle(STYLE_BORDER_RADIUS, 16); // Add to rootView (*sportingPauseOrContinueView_)->Add(&canvas_); (*sportingPauseOrContinueView_)->Add(&imgEnd_); // ����û�б����� (*sportingPauseOrContinueView_)->Add(&pauseOrContinueCheckBox_); (*sportingPauseOrContinueView_)->Add(&prePage); (*sportingPauseOrContinueView_)->Add(&PauseOrContinuePage); return (*sportingPauseOrContinueView_); } void SportingView::SetSportingRtcLabelText(Time currentTime) { char timeStr[20] = {0}; sprintf(timeStr, "%02d:%02d:%02d", currentTime.hours, currentTime.minutes, currentTime.seconds); sportingRtcLabel_.SetText(timeStr); sportingRtcLabel_.Invalidate(); } uint32_t SportingView::GetStep() { return std::stoi(std::string(stepLabel_.GetText())); } #pragma endregion #pragma region 运动结束无数据界面 EndOfSportNoDataView::EndOfSportNoDataView() { static_print_info("EndOfSportNoDataView::EndOfSportNoDataView"); SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); // InitLabel(remindLabel_, 34, 54, 179, "运动数据不足,\n本次锻炼数据将不保存!"); remindLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); remindLabel_.SetTextId(STR_ID_197); remindLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); remindLabel_.SetPosition(0, 179, 466, 47); remindLabelTip_.SetFont(TJD_VECTOR_FONT_FILENAME, 34); remindLabelTip_.SetTextId(STR_ID_198); remindLabelTip_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_WRAP); remindLabelTip_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); remindLabelTip_.SetPosition(60, 226, 346, 47); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_CONFIRM, SPORT_IMAGE_BIN_PATH); UiDrawImage(&imgConfirm_, 187, 352, imgInfo); imgConfirm_.SetTouchable(true); imgConfirm_.SetViewId("NoDataConfirm_"); imgConfirm_.SetOnClickListener(&noDataViewOnClickedListener_); Add(&remindLabel_); Add(&remindLabelTip_); Add(&imgConfirm_); } void EndOfSportNoDataView::ShowView() { TjdUiAppSportModel::GetInstance()->RemoveFile(str); SetVisible(true); } EndOfSportNoDataView::~EndOfSportNoDataView() { static_print_info("EndOfSportNoDataView Destory=======\n"); RemoveAll(); } #pragma endregion #pragma region 运动结束数据界面 EndOfSportDataView::EndOfSportDataView() { static_print_info("TjdUiAppSportView::NormalEndingViewInit..."); g_EndOfSportDataView = this; SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0); SetPosition(0, 0, OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); SetStyle(STYLE_BACKGROUND_OPA, 0); SetScrollBlankSize(20); SetHorizontalScrollState(false); SetThrowDrag(true); // 设置结束拖动时,是否产生惯性滑动动效 SetElastic(true); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); GPSMap_.SetPosition(126, 156, 214, 252); GPSMap_.SetTouchable(false); DataView_.SetPosition(0, 493, 466, 100); // InitLabel(dataViewTitlie_, 28, 176, 16, "运动结束"); dataViewTitlie_.SetFont(TJD_VECTOR_FONT_FILENAME, 28); dataViewTitlie_.SetTextId(STR_ID_199); dataViewTitlie_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_MARQUEE); dataViewTitlie_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); dataViewTitlie_.SetPosition(167, 17, 132, 40); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[0].imgIconResId, SPORT_IMAGE_BIN_PATH); UIDrawImageScale(&SportIcon_, 203, 60, imgInfo, 0.6, 0.6, 30, 30); InitView(); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_CONFIRM, SPORT_IMAGE_BIN_PATH); imgConfirm_.SetPosition(187, 333); // widget's left position and top position imgConfirm_.SetSrc(imgInfo); imgConfirm_.SetTouchable(true); imgConfirm_.SetViewId("DataConfirm_"); imgConfirm_.SetOnClickListener(&dataViewOnClickedListener_); Add(&dataViewTitlie_); Add(&SportIcon_); Add(&GPSMap_); Add(&DataView_); Add(&imgConfirm_); } void EndOfSportDataView::InitView(void) { static_print_info("InitView..."); canvas_.SetPosition(0, 0, 214, 252); canvas_.Resize(OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); canvas_.SetStyle(OHOS::STYLE_BACKGROUND_COLOR, 0xFF000000); canvas_.SetTouchable(false); ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_TIME, SPORT_IMAGE_BIN_PATH); UiDrawImage(&sportTimeIcon_, 60, 21, imgInfo); // InitLabel(sportTimeLabel_, 30, 126, 0, "运动时间"); sportTimeLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); sportTimeLabel_.SetTextId(STR_ID_200); sportTimeLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); sportTimeLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); sportTimeLabel_.SetPosition(126, 0, 124, 42); sportTimeLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curSportTime_, 60, 125, 39, "00:00:00", TJD_DIN_MEDIUM_FONT_FILENAME); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_HR, SPORT_IMAGE_BIN_PATH); UiDrawImage(&heartRateIcon_, 59, 166, imgInfo); // InitLabel(averageHeartRateLabel_, 30, 126, 139, "平均心率"); averageHeartRateLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); averageHeartRateLabel_.SetTextId(STR_ID_111); averageHeartRateLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); averageHeartRateLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); averageHeartRateLabel_.SetPosition(126, 139, 124, 42); averageHeartRateLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curAverageHeartRate_, 60, 130, 178, "---", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curAverageHeartRateUnitLabel_, 30, 230, 194, "Bpm"); curAverageHeartRateUnitLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_KCAL, SPORT_IMAGE_BIN_PATH); UiDrawImage(&calorieIcon_, 59, 295, imgInfo); // InitLabel(calorieLabel_, 30, 126, 284, "卡路里"); calorieLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); calorieLabel_.SetTextId(STR_ID_201); calorieLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); calorieLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); calorieLabel_.SetPosition(126, 284, 94, 42); calorieLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curCalorie_, 60, 125, 317, "0000", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curCalorieUnitLabel_, 30, 263, 333, "Kcal"); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_SPEED, SPORT_IMAGE_BIN_PATH); UiDrawImage(&speedIcon_, 62, 578, imgInfo); // InitLabel(speed_, 30, 126, 557, "配速"); speed_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); speed_.SetTextId(STR_ID_203); speed_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); speed_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); speed_.SetPosition(126, 557, 64, 42); speed_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curSpeed_, 60, 126, 591, "00'00'", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curSpeedUnitLabel_, 30, 164, 612, "min/km"); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_DISTANCE, SPORT_IMAGE_BIN_PATH); UiDrawImage(&sportDistanceIcon_, 60, 435, imgInfo); // InitLabel(sportDistanceLabel_, 30, 126, 418, "公里数"); sportDistanceLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); sportDistanceLabel_.SetTextId(STR_ID_202); sportDistanceLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); sportDistanceLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); sportDistanceLabel_.SetPosition(126, 418, 94, 42); sportDistanceLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curSportDistance_, 60, 125, 457, "0.00", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curSportDistanceUnitLabel_, 30, 295, 473, "Km"); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_STEP, SPORT_IMAGE_BIN_PATH); UiDrawImage(&stepIcon_, 60, 714, imgInfo); // InitLabel(curStepLabel_, 30, 126, 695, "步数"); curStepLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); curStepLabel_.SetTextId(STR_ID_204); curStepLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); curStepLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); curStepLabel_.SetPosition(126, 695, 64, 42); curStepLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curStep_, 60, 125, 735, "00000", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curStepUnitLabel_, 30, 295, 751, "Steps"); imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(IMG_SPORT_END_FREQUENCY, SPORT_IMAGE_BIN_PATH); UiDrawImage(&stepFrequencyIcon_, 62, 859, imgInfo); // InitLabel(stepFrequencyLabel_, 30, 126, 834, "步幅"); stepFrequencyLabel_.SetFont(TJD_VECTOR_FONT_FILENAME, 30); stepFrequencyLabel_.SetTextId(STR_ID_205); stepFrequencyLabel_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); stepFrequencyLabel_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_CENTER); stepFrequencyLabel_.SetPosition(126, 834, 64, 42); stepFrequencyLabel_.SetTextColor(Color::GetColorFromRGBA(0x6B, 0x6B, 0x6B, 0xff)); InitLabel(curStepFrequency_, 60, 125, 869, "0.0", TJD_DIN_MEDIUM_FONT_FILENAME); InitLabel(curStepFrequencyUnitLabel_, 30, 295, 890, "M"); TjdUiUtils::AdjustViewOffset(curAverageHeartRateUnitLabel_, curAverageHeartRate_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); TjdUiUtils::AdjustViewOffset(curCalorieUnitLabel_, curCalorie_, 15, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); TjdUiUtils::AdjustViewOffset(curSpeedUnitLabel_, curSpeed_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); TjdUiUtils::AdjustViewOffset(curSportDistanceUnitLabel_, curSportDistance_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); TjdUiUtils::AdjustViewOffset(curStepUnitLabel_, curStep_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); TjdUiUtils::AdjustViewOffset(curStepFrequencyUnitLabel_, curStepFrequency_, 11, TjdUiUtils::OffsetDirection::OFFSET_RIGHT); GPSMap_.Add(&canvas_); } void EndOfSportDataView::ChangeSportType(SportType type) { DataView_.RemoveAll(); DataView_.Add(&sportTimeIcon_); DataView_.Add(&sportTimeLabel_); DataView_.Add(&curSportTime_); DataView_.Add(&heartRateIcon_); DataView_.Add(&averageHeartRateLabel_); DataView_.Add(&curAverageHeartRateUnitLabel_); DataView_.Add(&curAverageHeartRate_); DataView_.Add(&calorieIcon_); DataView_.Add(&calorieLabel_); DataView_.Add(&curCalorieUnitLabel_); DataView_.Add(&curCalorie_); switch (SportingView::sportType) { case SPORT_TYPE_1: DataView_.Add(&sportDistanceIcon_); DataView_.Add(&sportDistanceLabel_); DataView_.Add(&curSportDistanceUnitLabel_); DataView_.Add(&curSportDistance_); DataView_.Add(&speedIcon_); DataView_.Add(&speed_); DataView_.Add(&curSpeedUnitLabel_); DataView_.Add(&curSpeed_); DataView_.Add(&stepIcon_); DataView_.Add(&curStep_); DataView_.Add(&curStepUnitLabel_); DataView_.Add(&curStepLabel_); DataView_.Add(&stepFrequencyLabel_); DataView_.Add(&curStepFrequencyUnitLabel_); DataView_.Add(&stepFrequencyIcon_); DataView_.Add(&curStepFrequency_); break; case SPORT_TYPE_2: DataView_.Add(&sportDistanceIcon_); DataView_.Add(&sportDistanceLabel_); DataView_.Add(&curSportDistanceUnitLabel_); DataView_.Add(&curSportDistance_); break; default: break; } auto height = DataView_.GetChildrenTail()->GetY() + DataView_.GetChildrenTail()->GetHeight(); DataView_.Resize(466, height); imgConfirm_.SetY(DataView_.GetY() + height + 54); } #define READ_DATA_FROM_FILE 0 void EndOfSportDataView::EndOfSportDataViewRefresh(std::string fileName) { static_print_info("EndOfSportDataView::EndOfSportDataViewRefresh\n"); char temp[20] = {0}; auto sportModel = TjdUiAppSportModel::GetInstance(); cJSON *json = sportModel->ReadAndParseJson(fileName.c_str()); #if 1 // 临时调试 std::vector trajectory = sportModel->TrackAnalysis(json); #else std::vector trajectory = { {22.580576, 113.917157}, {22.580627, 113.917229}, {22.580627, 113.917229}, {22.580765, 113.917386}, {22.58084, 113.917481}, {22.58094, 113.917589}, }; #endif DrawSportTrack(trajectory); // 释放 JSON 对象 cJSON_Delete(json); // static_print_info("===%s===\n", SportingView::GetInstance()->sportingRtcLabel_.GetText()); #if READ_DATA_FROM_FILE Time time = TjdUiAppSportView::GetInstance()->GetCurrentTime(sportModel->KeyValueAnalysis(json, "运动时间")); #else Time time = TjdUiAppSportView::GetInstance()->GetCurrentTime(SportingView::GetInstance()->sportingRtcLabel_.GetText()); // Time time = TjdUiAppSportView::GetInstance()->GetCurrentTime(sportModel->KeyValueAnalysis(json, "SportTime")); #endif int16_t tempDistance = 0; uint32_t totalTime = time.hours * 3600 + time.minutes * 60 + time.seconds; double distance = std::stof(std::string(SportingView::GetInstance()->distanceLabel_.GetText())); uint32_t step = std::stoi(std::string(SportingView::GetInstance()->stepLabel_.GetText())); auto iconIndex = TjdUiAppSportView::GetInstance()->currentIconIndex_; ImageInfo *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes(g_pv_Sport[iconIndex].imgIconResId, SPORT_IMAGE_BIN_PATH); if (imgInfo) SportIcon_.SetSrc(imgInfo); switch (SportingView::sportType) { case SPORT_TYPE_1: #if READ_DATA_FROM_FILE curSportDistance_.SetText(sportModel->KeyValueAnalysis(json, "公里数")); #else curSportDistance_.SetText(SportingView::GetInstance()->distanceLabel_.GetText()); #endif if (distance != 0) { float pace = totalTime / distance / 60.0; int minutes = static_cast(pace); int seconds = static_cast((pace - minutes) * 60); // 创建带单引号的目标字符串 stringstream finalStr; finalStr << minutes << "'" << setw(2) << setfill('0') << seconds << "\""; curSpeed_.SetText(finalStr.str().c_str()); printf("pace = %f, minutes = %d, seconds = %d\n", pace, minutes, seconds); // memset(temp, 0, sizeof(temp)); // sprintf(temp, "%02d'%02d\"", totalTime / distance, totalTime % distance); // curSpeed_.SetText(temp); // curSpeed_.SetText("00'00\""); } else { curSpeed_.SetText("00'00\""); } #if READ_DATA_FROM_FILE curStep_.SetText(sportModel->KeyValueAnalysis(json, "步数")); #else curStep_.SetText(SportingView::GetInstance()->stepLabel_.GetText()); #endif if (step) { memset(temp, 0, sizeof(temp)); tempDistance = (uint16_t)distance * 1000; sprintf(temp, "%d.%01d\"", tempDistance / step, tempDistance % step); curStepFrequency_.SetText(temp); // curStepFrequency_.SetText("0.0"); // 先用假数据 } else curStepFrequency_.SetText("0.0"); // 步频需要换算 break; case SPORT_TYPE_2: curSportDistance_.SetText(SportingView::GetInstance()->distanceLabel_.GetText()); break; case SPORT_TYPE_3: break; default: break; } #if READ_DATA_FROM_FILE curSportTime_.SetText(sportModel->KeyValueAnalysis(json, "运动时间")); curAverageHeartRate_.SetText(sportModel->KeyValueAnalysis(json, "平均心率")); curCalorie_.SetText(sportModel->KeyValueAnalysis(json, "卡路里")); #else printf("SportTime = %s\n", SportingView::GetInstance()->sportingRtcLabel_.GetText()); curSportTime_.SetText(SportingView::GetInstance()->sportingRtcLabel_.GetText()); curAverageHeartRate_.SetText(SportingView::GetInstance()->heartRateLabel_.GetText()); curCalorie_.SetText(SportingView::GetInstance()->caloriesLabel_.GetText()); #endif } OHOS::Point EndOfSportDataView::latLonToScreen(const Coordinate &coordinate, double minLat, double maxLat, double minLon, double maxLon, int screenWidth, int screenHeight) { Point point; point.x = (coordinate.longitude - minLon) / (maxLon - minLon) * screenWidth; point.y = screenHeight - (coordinate.latitude - minLat) / (maxLat - minLat) * screenHeight; // y轴翻转 return point; } void EndOfSportDataView::DrawSportTrack(std::vector trajectory) { canvas_.Clear(); Paint paint; // paint.SetStyle(Paint::PaintStyle::FILL_STYLE); paint.SetStrokeColor(Color::Green()); paint.SetStrokeWidth(3); paint.SetOpacity(OPA_OPAQUE); // 获取最小和最大纬度和经度 double minLatitude = std::numeric_limits::max(); double maxLatitude = std::numeric_limits::lowest(); double minLongitude = std::numeric_limits::max(); double maxLongitude = std::numeric_limits::lowest(); for (const auto &coord : trajectory) { if (coord.latitude < minLatitude) minLatitude = coord.latitude; if (coord.latitude > maxLatitude) maxLatitude = coord.latitude; if (coord.longitude < minLongitude) minLongitude = coord.longitude; if (coord.longitude > maxLongitude) maxLongitude = coord.longitude; } const int screenWidth = 214; const int screenHeight = 252; bool isFirst = true; // 用于跟踪是否是第一个点 // 转换并输出屏幕坐标 for (const auto &point : trajectory) { auto position = latLonToScreen(point, minLatitude, maxLatitude, minLongitude, maxLongitude, screenWidth, screenHeight); static_print_info("Screen: (%d, %d)\n", position.x, position.y); if (isFirst) { canvas_.BeginPath(); // canvas_.SetStartPosition(position); canvas_.MoveTo(position); isFirst = false; // 更新状态为不是第一个点 } else { // canvas_.DrawLine(position, paint); canvas_.LineTo(position); } } canvas_.DrawPath(paint); } void EndOfSportDataView::ShowView() { static_print_info("====str=%s=====\n", str); TjdUiUtils::ScrollByTop(*this); // std::string new_fileName = TjdUiAppSportModel::GetInstance()->RenameSportDataFile(str); printf("state = %d\n", TjdUiAppSportView::GetInstance()->GetGPState()); if (TjdUiAppSportView::GetInstance()->GetGPState()) { DataView_.SetY(493); GPSMap_.SetVisible(true); } else { DataView_.SetY(193); GPSMap_.SetVisible(false); } ChangeSportType(SportingView::sportType); EndOfSportDataViewRefresh(str); SetVisible(true); tjd_service_send_sport_end_record_data(str); } EndOfSportDataView *EndOfSportDataView::GetInstance() { return g_EndOfSportDataView; } EndOfSportDataView::~EndOfSportDataView() { static_print_info("EndOfSportDataView Destory=======\n"); g_EndOfSportDataView = nullptr; RemoveAll(); GPSMap_.RemoveAll(); DataView_.RemoveAll(); } #pragma endregion #pragma region 编辑运动 EditSportView::EditSportView() { g_pv_EditSportView = this; SetPosition(0, 0, 466, 466); SetStyle(STYLE_BACKGROUND_OPA, 0); SetDraggable(true); SetOnDragListener(TjdUiAppSportPresenter::GetInstance()); // InitLabelHorCenter(editTitle_, 28, 17, 466, "编辑运动"); editTitle_.SetFont(TJD_VECTOR_FONT_FILENAME, 28); editTitle_.SetTextId(STR_ID_207); // editTitle_.SetLineBreakMode(OHOS::UILabel::LINE_BREAK_ADAPT); editTitle_.SetAlign(OHOS::TEXT_ALIGNMENT_CENTER, OHOS::TEXT_ALIGNMENT_TOP); editTitle_.SetPosition(0, 17, 466, 100); auto editListItemInfo_ = TjdUiAppSportView::GetInstance()->GetEditItemList(); editListAdapterPtr_ = new TjdUITransformListGroupAdapter>(*editListItemInfo_); editListView_ = new TjdUITransformListGroup(editListAdapterPtr_); editListView_->AddCustomView(&editTitle_, TjdUITransformListGroup::CustomViewPos::TOP); // Add(&editTitle_); Add(editListView_); } EditSportView::~EditSportView() { g_pv_EditSportView = nullptr; RemoveAll(); } void EditSportView::ShowView() { OHOS::FocusManager::GetInstance()->ClearFocus(); editListView_->RequestFocus(); SetVisible(true); } void EditSportView::HideView() { OHOS::FocusManager::GetInstance()->ClearFocus(); SetVisible(false); } EditSportView *EditSportView::GetInstance(void) { return g_pv_EditSportView; } #pragma endregion bool GetIfReturnToDial(OHOS::ImageInfo **imgInfo) { if (returnToDial) { *imgInfo = ImageCacheManager::GetInstance().LoadOneInMultiRes( g_pv_Sport[TjdUiAppSportView::currentIconIndex_].imgIconResId, SPORT_IMAGE_BIN_PATH); return true; } else { *imgInfo = nullptr; return false; } } #pragma region 321倒计时 #pragma endregion #pragma region 321倒计时 #pragma endregion } // namespace TJD