1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BusinessError } from '@kit.BasicServicesKit'; 17import { display, window } from '@kit.ArkUI'; 18import { ConfigurationConstant } from '@kit.AbilityKit'; 19import { CONFIGURATION, STRINGCONFIGURATION } from '../common/Constants'; 20import { Side, TopView, VideoDes } from '../view/Side'; 21import { logger } from '../utils/Logger'; 22 23/** 24 * 功能描述: 本示例实现了tabContent内容可以在tabBar上显示并且tabBar可以响应滑动事件的功能。 25 * 26 * 推荐场景: 小视频播放场景 27 * 28 * 核心组件: 29 * 1. Tabs 30 * 31 * 实现步骤: 32 * 1. 创建Tabs组件,将barHeight设置为0。 33 * 2. 创建自定义tabBar组件。 34 * 3. 将TabContent的内容分为上下两部分,上半部高度为100% - 60vp,存放video组件,下部分高度为60vp,存放进度条,设置滑动手势响应事件。 35 * 4. 将Tabs组件的zIndex属性设置为2,tabContent的视图就可以堆叠在自定义tabBar之上。 36 * 5. 再设置hitTestBehavior属性使被覆盖的自定义的tabBar可以响应点击事件。 37 */ 38@Component 39export struct TabContentOverFlowComponent { 40 @State tabArray: string[] = ['app.string.tabcontentoverflow_homepage', 'app.string.tabcontentoverflow_video', 'app.string.tabcontentoverflow_mall', 'app.string.tabcontentoverflow_mine']; 41 @State imageArray: string[] = ['app.media.tabcontentoverflow_homepage', 'app.media.tabcontentoverflow_video', 'app.media.tabcontentoverflow_mall', 'app.media.tabcontentoverflow_mine']; 42 @State imageClickArray: string[] = ['app.media.tabcontentoverflow_homepage_filled', 'app.media.tabcontentoverflow_video_filled', 'app.media.tabcontentoverflow_mall_filled', 'app.media.tabcontentoverflow_mine_filled']; 43 @State index: number = 1; 44 @State offsetX: number = 0; // 用来记录实时拖动的距离 45 @State positionX: number = 0; // 用来记录拖动后的距离 46 @State playTime: string = ''; // 用来记录现在播放的时间 47 @State totalTime: number = 0; // 用来记录视频全部时长 48 @State isPlay: boolean = false; // 用来控制播放状态 49 @State isTouch: boolean = false; // 是否处于拖动状态 50 @State isTextButtonVisible: boolean = true; 51 private isSeek: boolean = false; // 是否拖拽跳转 52 private tabsController: TabsController = new TabsController(); 53 private videoController: VideoController = new VideoController(); 54 private panOption: PanGestureOptions = new PanGestureOptions({ 55 direction: PanDirection.Left | PanDirection.Right 56 }); // 设置拖动方向,只能左右拖动。 57 private screenW: number = px2vp(display.getDefaultDisplaySync().width); // 获取设备宽度 58 59 // 进入案例时设置状态栏颜色 60 aboutToAppear(): void { 61 setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_DARK); 62 } 63 64 // 退出案例时设置状态栏颜色,避免影响其他案例。 65 aboutToDisappear(): void { 66 setStatusBar(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT); 67 } 68 69 private dragAnimation() { 70 animateTo({ 71 duration: CONFIGURATION.TABCONTENT_OVERFLOW_TOAST_DURATION, 72 curve: Curve.EaseOut, 73 }, () => { 74 this.isTouch = true; 75 }); 76 } 77 78 @Builder 79 videoTabContent() { 80 /** 81 * 高性能布局策略: 界面深度的增加会提升渲染和计算影响性能。推荐使用扁平化设计,如RelativeContainer,以简化布局结构,降低组件层级,从而提升渲染效率。 82 * 优化布局性能:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/performance/reduce-view-nesting-levels.md 83 */ 84 RelativeContainer() { 85 Video({ 86 src: $rawfile('tabcontentoverflow_play_video.MP4'), 87 currentProgressRate: PlaybackSpeed.Speed_Forward_1_00_X, 88 previewUri: $r('app.media.tabcontentoverflow_preview'), 89 controller: this.videoController 90 }) 91 .height($r('app.string.tabcontentoverflow_video_height')) 92 .width($r('app.string.tabcontentoverflow_full_size')) 93 .objectFit(ImageFit.Cover) 94 .autoPlay(false) 95 .controls(false) 96 .onPrepared((event) => { 97 if (event !== undefined) { 98 this.totalTime = event.duration; 99 } 100 }) 101 .onFinish(() => { 102 this.isPlay = false; 103 }) 104 .onUpdate((event) => { 105 if (event !== undefined) { 106 if (!this.isTouch) { 107 if (!this.isSeek) { 108 // 当没有进行拖动进度条时,进度条根据播放进度进行变化。 109 this.offsetX = 110 event.time / this.totalTime * (this.screenW - CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER); 111 this.positionX = this.offsetX; 112 } else { 113 this.isSeek = false; 114 } 115 } 116 } 117 }) 118 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO) 119 .alignRules({ 120 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: VerticalAlign.Top }, 121 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start } 122 }) 123 .onClick(() => { 124 if (this.isPlay) { 125 this.isPlay = false; 126 this.videoController.pause(); 127 } else { 128 this.isPlay = true; 129 this.videoController.start(); 130 } 131 }) 132 // 播放按钮 133 Image($r('app.media.tabcontentoverflow_play')) 134 .width($r('app.integer.tabcontentoverflow_image_width')) 135 .height($r('app.integer.tabcontentoverflow_image_height')) 136 .alignRules({ 137 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Top }, 138 bottom: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Bottom }, 139 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 140 right: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.End }, 141 }) 142 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_IMAGE) 143 .onClick(() => { 144 if (this.isPlay) { 145 this.isPlay = false; 146 this.videoController.pause(); 147 } else { 148 this.isPlay = true; 149 this.videoController.start(); 150 } 151 }) 152 .visibility(this.isPlay ? Visibility.Hidden : Visibility.Visible) 153 // 展示视频相关信息,拖动进度条时隐藏。 154 VideoDes() 155 .alignRules({ 156 bottom: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Bottom }, 157 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 158 }) 159 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEODES) 160 .margin({ bottom: $r('app.integer.tabcontentoverflow_video_des_margin_bottom') }) 161 .visibility(this.isTouch ? Visibility.Hidden : Visibility.Visible) 162 // 展示视频播放界面右侧用户头像、视频评论数量、收藏数量、分享数量、作者是否被用户关注等信息,拖动进度条时隐藏。 163 Side() 164 .alignRules({ 165 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Center }, 166 right: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.End }, 167 }) 168 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_SIDE) 169 .margin({ top: $r('app.integer.tabcontentoverflow_side_margin_top') }) 170 .visibility(this.isTouch ? Visibility.Hidden : Visibility.Visible) 171 // 顶部视图 172 TopView() 173 .alignRules({ 174 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Top }, 175 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 176 }) 177 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TOPVIEW) 178 // 拖动进度条时展示现在播放哪个到具体的时间点 179 Text(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_PLAYTIME_TEXT + this.playTime) 180 .fontSize($r('app.integer.tabcontentoverflow_play_time_text_font_size')) 181 .width($r('app.integer.tabcontentoverflow_play_time_text_width')) 182 .height($r('app.integer.tabcontentoverflow_play_time_text_height')) 183 .textAlign(TextAlign.End) 184 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_PLAYTIME_TEXT_ID) 185 .fontColor($r('app.color.tabcontentoverflow_play_time_text_color')) 186 .alignRules({ 187 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Bottom }, 188 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Center }, 189 }) 190 .visibility(this.isTouch ? Visibility.Visible : Visibility.Hidden) 191 .margin({ 192 left: $r('app.integer.tabcontentoverflow_play_time_text_margin'), 193 top: $r('app.integer.tabcontentoverflow_play_time_text_margin') 194 }) 195 // 拖动进度条时展示视频总时长 196 Text(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TOTALTIME_TEXT + this.totalTime) 197 .fontSize($r('app.integer.tabcontentoverflow_play_time_text_font_size')) 198 .width($r('app.integer.tabcontentoverflow_play_time_text_width')) 199 .height($r('app.integer.tabcontentoverflow_play_time_text_height')) 200 .textAlign(TextAlign.Start) 201 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TOTALTIME_TEXT_ID) 202 .fontColor($r('app.color.tabcontentoverflow_total_time_text_color')) 203 .alignRules({ 204 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_PLAYTIME_TEXT_ID, align: VerticalAlign.Top }, 205 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_PLAYTIME_TEXT_ID, align: HorizontalAlign.End }, 206 }) 207 .visibility(this.isTouch ? Visibility.Visible : Visibility.Hidden) 208 /** 209 * TODO: 知识点:使用三个Text组件来模拟播放进度条,第一个text位置不变,宽度不变。 210 * 第二个text根据this.offsetX来变换宽度。第三个text根据this.offsetX来translate该组件在x轴的位置。 211 */ 212 RelativeContainer() { 213 Text() 214 .width(this.screenW - CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER) 215 .height(this.isTouch ? $r('app.integer.tabcontentoverflow_text1_touch_height') : $r('app.integer.tabcontentoverflow_text1_height')) 216 .borderRadius(this.isTouch ? $r('app.integer.tabcontentoverflow_text1_touch_border_radius') : $r('app.integer.tabcontentoverflow_text1_borderradius')) 217 .backgroundColor($r('app.color.tabcontentoverflow_text1_background_color')) 218 .translate({ 219 y: this.isTouch ? CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_TOUCH_TRANSLATE 220 : CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_TRANSLATE 221 }) 222 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTONE_ID) 223 .margin({ 224 top: $r('app.integer.tabcontentoverflow_text1_margin_top'), 225 left: $r('app.integer.tabcontentoverflow_text1_margin_left') 226 }) 227 Text() 228 .width(this.offsetX) 229 .height(this.isTouch ? $r('app.integer.tabcontentoverflow_text1_touch_height') : $r('app.integer.tabcontentoverflow_text1_height')) 230 .borderRadius(this.isTouch ? $r('app.integer.tabcontentoverflow_text1_touch_border_radius') : $r('app.integer.tabcontentoverflow_text1_borderradius')) 231 .backgroundColor($r('app.color.tabcontentoverflow_text2_background_color')) 232 .translate({ 233 y: this.isTouch ? CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_TOUCH_TRANSLATE 234 : CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_TRANSLATE 235 }) 236 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTTWO_ID) 237 .alignRules({ 238 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTONE_ID, align: VerticalAlign.Top }, 239 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTONE_ID, align: HorizontalAlign.Start }, 240 }) 241 Text() 242 .width($r('app.integer.tabcontentoverflow_text3_width')) 243 .height($r('app.integer.tabcontentoverflow_text3_height')) 244 .borderRadius($r('app.integer.tabcontentoverflow_text3_border_radius')) 245 .backgroundColor($r('app.color.tabcontentoverflow_text2_background_color')) 246 .translate({ x: this.offsetX }) 247 .visibility(this.isTextButtonVisible ? Visibility.Visible : Visibility.None) 248 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTTHREE_ID) 249 .alignRules({ 250 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTONE_ID, align: VerticalAlign.Top }, 251 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TEXTONE_ID, align: HorizontalAlign.Start }, 252 }) 253 .margin({ 254 top: CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_THREE_MARGIN_TOP, 255 left: CONFIGURATION.TABCONTENT_OVERFLOW_TEXT_THREE_MARGIN_LEFT 256 }) 257 } 258 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_RELATIVE_CONTAINER) 259 .alignRules({ 260 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Bottom }, 261 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 262 }) 263 .width(this.screenW) 264 .height($r('app.integer.tabcontentoverflow_tabbar_height')) 265 // 左右拖动触发该手势事件 266 .gesture( 267 PanGesture(this.panOption) 268 .onActionStart(() => { 269 this.dragAnimation(); 270 this.isTextButtonVisible = false; 271 this.isSeek = true; 272 }) 273 /** 274 * TODO: 性能知识点: onActionUpdate是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。 275 * 优化系统使用,减少冗余操作:参考性能优化指南 276 */ 277 .onActionUpdate((event: GestureEvent) => { 278 let playTime = Math.floor(this.offsetX / (this.screenW - 279 CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER) * this.totalTime); 280 this.offsetX = this.positionX + event.offsetX; 281 if (this.offsetX <= CONFIGURATION.TABCONTENT_OVERFLOW_ZERO) { 282 this.offsetX = CONFIGURATION.TABCONTENT_OVERFLOW_ZERO; 283 } 284 if (this.offsetX >= this.screenW - CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER) { 285 this.offsetX = this.screenW - CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER; 286 } 287 if (playTime >= CONFIGURATION.TABCONTENT_OVERFLOW_TEN) { 288 this.playTime = playTime.toString(); 289 } else { 290 this.playTime = STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TIME_ZERO + playTime.toString(); 291 } 292 }) 293 .onActionEnd(() => { 294 if (this.positionX === this.offsetX) { // 进度条未发生改变 295 this.isSeek = false; 296 } else { 297 // 拖动进度条发生改变后通过this.videoController.setCurrentTime来精准定位视频现在播放位置。 298 this.videoController.setCurrentTime(Number((this.offsetX / 299 (this.screenW - CONFIGURATION.TABCONTENT_OVERFLOW_INTERVAL_NUMBER) * 300 this.totalTime).toFixed(3)), SeekMode.Accurate); 301 this.positionX = this.offsetX; 302 } 303 this.isTextButtonVisible = true; 304 this.isTouch = false; 305 }) 306 ) 307 } 308 } 309 310 build() { 311 RelativeContainer() { 312 // TODO: 知识点:将barHeight设置为0,预留60vp给自定义tabBar,TabContent的高度则可以使用calc(100% - 60vp)获取。 313 Tabs({ index: this.index, controller: this.tabsController }) { 314 TabContent() { 315 Text(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_HOMEPAGE) 316 .fontSize($r('app.integer.tabcontentoverflow_tabcontent_text_fontsize')) 317 } 318 .align(Alignment.Center) 319 .height($r('app.string.tabcontentoverflow_video_height')) 320 .width($r('app.string.tabcontentoverflow_full_size')) 321 322 TabContent() { 323 this.videoTabContent(); 324 } 325 326 TabContent() { 327 Text(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_MALL) 328 .fontSize($r('app.integer.tabcontentoverflow_tabcontent_text_fontsize')) 329 } 330 .align(Alignment.Center) 331 .height($r('app.string.tabcontentoverflow_video_height')) 332 .width($r('app.string.tabcontentoverflow_full_size')) 333 334 TabContent() { 335 Text(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_MINE) 336 .fontSize($r('app.integer.tabcontentoverflow_tabcontent_text_fontsize')) 337 } 338 .align(Alignment.Center) 339 .height($r('app.string.tabcontentoverflow_video_height')) 340 .width($r('app.string.tabcontentoverflow_full_size')) 341 } 342 // TODO: 知识点:将zIndex设置为2,TabContent将在tabBar之上,显示的效果就是TabContent外溢的部分在tabBar上。 343 .zIndex(CONFIGURATION.TABCONTENT_OVERFLOW_ZINDEX) 344 .scrollable(false) 345 .barHeight($r('app.integer.tabcontentoverflow_tabs_barheight')) 346 .animationDuration(CONFIGURATION.TABCONTENT_OVERFLOW_TABS_DURATION) 347 .onChange((index: number) => { 348 this.index = index; 349 }) 350 /** 351 * TODO: 知识点:hitTestBehavior属性可以实现在复杂的多层级场景下, 352 * 一些组件能够响应手势和事件,而一些组件不能响应手势和事件。 353 * HitTestMode.Transparent的效果为,自身响应触摸测试,不会阻塞兄弟节点的触摸测试。 354 */ 355 .hitTestBehavior(HitTestMode.Transparent) 356 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TABS) 357 .alignRules({ 358 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: VerticalAlign.Top }, 359 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 360 }) 361 362 // 页签 363 Row() { 364 ForEach(this.tabArray, (item: string, index: number) => { 365 Column() { 366 Image(this.index === index ? $r(this.imageClickArray[index]) : $r(this.imageArray[index])) 367 .width($r('app.integer.tabcontentoverflow_row_column_image_width')) 368 .height($r('app.integer.tabcontentoverflow_row_column_image_height')) 369 Text($r(item)) 370 .fontSize($r('app.integer.tabcontentoverflow_row_column_text_font_size')) 371 .fontColor(this.index === index ? $r('app.color.tabcontentoverflow_click_color') : $r('app.color.tabcontentoverflow_white')) 372 } 373 .width($r('app.integer.tabcontentoverflow_row_column_width')) 374 .margin({ top: $r('app.integer.tabcontentoverflow_margin_samll') }) 375 // 为将底部视图扩展到非安全区域,可将原本60vp的高度设置为100vp。 376 .height($r('app.integer.tabcontentoverflow_row_column_height')) 377 .onClick(() => { 378 this.index = index; 379 this.tabsController.changeIndex(this.index); 380 }) 381 }) 382 } 383 .offset({ 384 y: $r('app.integer.tabcontentoverflow_row_offset') 385 }) 386 .width($r('app.string.tabcontentoverflow_full_size')) 387 // 扩展至所有非安全区域 388 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]) 389 .backgroundColor($r('app.color.tabcontentoverflow_row_background')) 390 .justifyContent(FlexAlign.SpaceAround) 391 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TABBAR) 392 .alignRules({ 393 top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: VerticalAlign.Bottom }, 394 left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start }, 395 }) 396 } 397 } 398} 399 400async function setStatusBar(currentMode: number): Promise<void> { 401 // 获取应用主窗口。 402 let windowClass: window.Window; 403 const windowStage: window.WindowStage = 404 AppStorage.get(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_WINDOW_STAGE) as window.WindowStage; 405 windowStage.getMainWindow((err, data) => { 406 if (err.code) { 407 logger.error('Failed to get Main Window. Cause: ' + JSON.stringify(err)); 408 return; 409 } 410 windowClass = data; 411 let statusBarColor = ''; 412 let statusBarContentColor = ''; 413 if (currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) { 414 statusBarColor = STRINGCONFIGURATION.TABCONTENT_OVERFLOW_BLACK; 415 statusBarContentColor = STRINGCONFIGURATION.TABCONTENT_OVERFLOW_WHITE; 416 } else { 417 statusBarColor = STRINGCONFIGURATION.TABCONTENT_OVERFLOW_WHITE; 418 statusBarContentColor = STRINGCONFIGURATION.TABCONTENT_OVERFLOW_BLACK; 419 } 420 const sysBarProps: window.SystemBarProperties = { 421 statusBarColor: statusBarColor, // 状态栏背景颜色 422 statusBarContentColor: statusBarContentColor // 状态栏文字颜色 423 }; 424 // TODO: 知识点:调用setWindowSystemBarProperties()设置状态栏的颜色 425 windowClass.setWindowSystemBarProperties(sysBarProps, (err: BusinessError) => { 426 const errCode: number = err.code; 427 if (errCode) { 428 logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); 429 return; 430 } 431 }); 432 }) 433} 434