HarmonyOS基础:如何使tabbar/navbar背景色不能衍生到状态栏和导航栏? 原创

黑臂麒麟
发布于 2024-11-19 14:45
浏览
0收藏

鸿蒙应用窗口全屏设置指南

问题背景

在开发鸿蒙应用时,当使用Tabs组件时会遇到一个常见问题:Tabs组件只能放置在内容区域,而导航栏和状态栏区域会保持原有的背景颜色,这样会导致整体视觉体验不统一,影响应用的美观性。

解决方案

1. 窗口全屏布局方案

调用窗口强制全屏布局接口(setWindowLayoutFullScreen())实现界面元素覆盖到状态栏和导航条,获取到状态栏和导航条高度后进行避让处理
该布局方案相对灵活,开发者可以通过获取到状态栏和导航条的区域,从而进行避让处理。

  1. 调用setWindowLayoutFullScreen()接口设置窗口全屏。
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

export default class EntryAbility extends UIAbility {
  // ...

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        return;
      }

      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      // 1. 设置窗口全屏
      let isLayoutFullScreen = true;
      windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
        .then(() => {
          console.info('Succeeded in setting the window layout to full-screen mode.');
        })
        .catch((err: BusinessError) => {
          console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
        });
    });
  }
}
  1. 使用getWindowAvoidArea()接口获取布局遮挡区域(例如状态栏、导航条)
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        return;
      }

      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      // 1. 设置窗口全屏
      // ...

      // 2. 获取布局避让遮挡的区域
      let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
      let avoidArea = windowClass.getWindowAvoidArea(type);
      let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度
      AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); // 创建本地存储
    });
  }
}
  1. 根据遮挡区域高度,调整页面内容区域位置,实现避让效果。
let storage = LocalStorage.getShared();

@Entry(storage)
@Component
struct Index {
  bottomRectHeight: string = AppStorage.get<number>('bottomRectHeight') + 'px';

  build() {
    Row() {
      Column() {
        Row() {
          Text('ROW1').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW2').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW3').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW4').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW5').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)

        Row() {
          Text('ROW6').fontSize(40)
        }.backgroundColor(Color.Orange).padding(20)
      }
      .width('100%')
      .height('100%')
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.SpaceBetween)
      .backgroundColor('#008000')
    }
    .margin({ bottom: this.bottomRectHeight }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
  }
}

2. 组件安全区方案

如果上述全屏方案不适合您的应用场景,还可以使用组件安全区方案。通过设置组件的expandSafeArea属性,可以让组件扩展到系统安全区以外的区域。

图例:界面元素自动避让状态栏和导航条示意图
HarmonyOS基础:如何使tabbar/navbar背景色不能衍生到状态栏和导航栏?-鸿蒙开发者社区
针对上面的情况,状态栏和导航条不匹配问题,可以通过窗口的背景色来实现统一背景色效果。使用setWindowBackgroundColor()接口设置窗口背景色。

// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // ...

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        return;
      }

      // 设置全窗颜色和应用内容颜色一致
      let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
      windowClass.setWindowBackgroundColor('#008000'); // 设置窗口背景色
    });
  }
}

在设置窗口背景色后,把页面内容背景也设置和窗口颜色一样,从而实现统一背景色效果。

// Index.ets  
@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('Hello World').fontSize(40)
    }
    .backgroundColor('#008000')
  }
}

这样就实现了状态栏和导航条区域与页面内容背景色一致的效果。

那如果状态栏和导航条和页面内容颜色不同怎么办?

可以通过设置组件的expandSafeArea属性来扩展安全区域,并设置不同的背景色,个人比较推荐这个方案,因为可以实现状态栏和导航条区域与页面内容背景色不一致/一致的效果,非常灵活。
例如:

// xxx.ets
@Entry
@Component
struct Example {
  build() {
    Column() {
      Row() {
        Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }
      .backgroundColor('#F08080')
      // 设置顶部绘制延伸到状态栏
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])

      Row() {
        Text('ROW2').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW3').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW4').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW5').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }
      .backgroundColor(Color.Orange)
      // 设置底部绘制延伸到导航条
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
    }
    .width('100%').height('100%').alignItems(HorizontalAlign.Center)
    .backgroundColor('#008000')
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

效果如下:
HarmonyOS基础:如何使tabbar/navbar背景色不能衍生到状态栏和导航栏?-鸿蒙开发者社区

引用:

@ohos.window (窗口)
开发应用沉浸式效果
获取状态栏高度的方法

结语

本篇文章的内容结束了。文章错误/不完整的地方,望多指点;
望更多小伙伴们加入harmonyOS开发大家庭,壮大生态圈,让鸿蒙更好,让国产手机应用(物联网)系统更强大。
鸿蒙5.0已经在公测了。和小伙伴一起加油,鸿蒙不仅仅应用开发系统。也会在物联网等领域大展拳脚。鸿蒙之父说:“手机端只是鸿蒙的5%的潜能。应用开发只是第一步,还有更多潜能供我们发觉开发"。
如对你学习有所帮助,希望可爱你动动小手,关注、点赞、收藏;

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐