全面屏手机的沉浸式状态栏自适应

场景:在使用Navigation组件的时候发现沉浸式状态栏没有做安全宽度的自适应,效果如下:

全面屏手机的沉浸式状态栏自适应-鸿蒙开发者社区

可以看到NavBar与手机状态栏有明显重叠现象,这样很影响用户体验。

HarmonyOS
2024-05-26 11:31:26
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
morning_dxm

使用的核心API

setWindowLayoutFullScreen

getWindowAvoidArea

核心代码解释

实现该场景主要需要在我们设置setWindowLayoutFullScreen为true开启全屏区域显示的时候,需要将Navigation组件顶部的状态栏区域空出来,所以我这里在Navigation组件上面添加了一个专门用户适配安全高度的Row里面没有内容,仅仅用于将Navigation组件顶部的区域空出来,然后通过getWindowAvoidArea方法获取系统的规避区域,将状态栏的高度给Row组件,以此来达到适配安全区域的效果。

核心代码如下:

import window from '@ohos.window'; 
import fs from '@ohos.file.fs'; 
import { BusinessError } from '@ohos.base'; 
import common from '@ohos.app.ability.common'; 
 
@Entry 
@Component 
struct Index { 
  @State topSafeHeight: number = 0 
  @State testList: Array<number> = [] 
  @State show: boolean = true 
  @State statusBackgroundColor: Color = 0x03ffffff 
 
  async aboutToAppear() { 
    for (let i = 0; i < 20; i++) { 
      this.testList.push(i) 
    } 
    // 顶部安全高度适配 
    let w = await window.getLastWindow(getContext(this)) 
    await w.setWindowLayoutFullScreen(true) 
    this.topSafeHeight = px2vp(w.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height) 
  } 
 
  build() { 
    Stack({ alignContent: Alignment.TopStart }) { 
      Image($r("app.media.startIcon")).width("100%") 
      Column() { 
        // 顶部安全高度适配 
        Row() { 
        }.height(this.topSafeHeight) 
        .width("100%") 
        .backgroundColor(this.statusBackgroundColor) 
        .animation({ 
          duration: 300, 
          curve: Curve.Friction, 
          iterations: 1, 
          playMode: PlayMode.Alternate 
        }) 
 
        Navigation() { 
          Panel(this.show) { 
            ForEach(this.testList, (item: number) => { 
              Text("我是测试数据" + item).fontSize(28).margin({ top: 8, bottom: 8 }) 
            }) 
          } 
          .type(PanelType.Foldable) 
          .mode(PanelMode.Full) 
          .dragBar(true) // 默认开启 
          .showCloseIcon(false) // 显示关闭图标 
          .onChange((width: number, height: number, mode: PanelMode) => { 
            console.info(`width:${width},height:${height},mode:${mode}`) 
            if (mode == 2) { 
              this.statusBackgroundColor = 0xffffffff 
            } else { 
              this.statusBackgroundColor = 0x03ffffff 
 
            } 
          }) 
        } 
        .title("顶部导航栏") 
        .titleMode(NavigationTitleMode.Mini) 
        .backgroundColor(this.statusBackgroundColor) 
        .animation({ 
          duration: 300, 
          curve: Curve.Friction, 
          iterations: 1, 
          playMode: PlayMode.Alternate 
        }) 
      } 
    }.width("100%") 
  } 
}

总结

  • 当前demo的内容展示区域是使用panel组件实现,有一个自定义costemPanel的实现方案,暂未适配。
  • 当前的动画只有两个状态变化,更好的效果应该是随着内容区域的滑动而慢慢变化,暂未实现。

实现效果

注明适配的版本信息

IDE:DevEco    Studio 4.0.3.600

SDK:HarmoneyOS    4.0.10.11

分享
微博
QQ
微信
回复
2024-05-27 11:42:01
相关问题
HarmonyOS 沉浸状态栏
117浏览 • 1回复 待解决
如何实现沉浸状态栏
534浏览 • 1回复 待解决
如何设置沉浸状态栏
2593浏览 • 1回复 待解决
HarmonyOS 沉浸状态栏最佳实践
301浏览 • 1回复 待解决
沉侵状态栏获取状态栏高度为0
395浏览 • 1回复 待解决
HarmonyOS 如何获取手机状态栏高度?
173浏览 • 1回复 待解决
获取状态栏高度方法
1981浏览 • 1回复 待解决
如何设置状态栏和导航颜色
2941浏览 • 1回复 待解决
获取状态栏与导航高度
644浏览 • 1回复 待解决