HarmonyOS 修改状态栏颜色 沉浸式状态栏

状态栏的修改和沉浸式可以参考官方文档:https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-immersive-V5

下面是我参考官方文档实现的效果:

具体的代码实现是使用官方的方案二,设置页面全屏,获取状态栏和导航栏的高度,设置安全距离实现。

一、在Index.ets页面获取状态栏和导航栏的高度

import { Home } from 'home';
import { Mine } from 'mine';
import { common } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';


//沉浸式状态栏相关对象
const uiAbilityContext = getContext(this) as common.UIAbilityContext;
const statusBarType = window.AvoidAreaType.TYPE_SYSTEM;
const navBarType = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;

//状态栏和导航栏高度封装类
interface AvoidArea {
  topRectHeight: number
  bottomRectHeight: number
}

@Entry
@Component
struct Index {
  @Provide indexPathStack: NavPathStack = new NavPathStack()
  //当前选中的下标
  @State activeTabIndex: number = 0
  private tabsController: TabsController = new TabsController();
  @State onPageResume: boolean = false
  private windowClass = uiAbilityContext.windowStage.getMainWindowSync();
  @State avoidArea: AvoidArea = { topRectHeight: 0, bottomRectHeight: 0 };


  onShown() {
    this.windowClass.setWindowLayoutFullScreen(true);
    this.setAvoidArea()
    this.windowClass.on('avoidAreaChange', this.onAvoidAreaChange)
  }

  // DocsDot
  onHidden() {
    this.windowClass.setWindowLayoutFullScreen(false);
    this.windowClass.off('avoidAreaChange', this.onAvoidAreaChange)
  }

  // DocsDot

  setAvoidArea() {
    // status bar area
    const statusBarArea = this.windowClass.getWindowAvoidArea(statusBarType);
    this.avoidArea.topRectHeight = statusBarArea.topRect.height;
    // navigation bar area
    const navBarArea = this.windowClass.getWindowAvoidArea(navBarType);
    this.avoidArea.bottomRectHeight = navBarArea.bottomRect.height;
  }

  onAvoidAreaChange = (data: window.AvoidAreaOptions) => {
    if (data.type === statusBarType) {
      this.avoidArea.topRectHeight = data.area.topRect.height;
    } else if (data.type === navBarType) {
      this.avoidArea.bottomRectHeight = data.area.bottomRect.height;
    }
  }

  // DocsCode 1

  @Builder
  tabBarBuilder(title: string, targetIndex: number, selectIcon: Resource, unSelectIcon: Resource) {
    Column() {
      ......
    }
  }

  build() {
    Navigation(this.indexPathStack) {
      Column() {
        Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
          TabContent() {
            Home({ statusBarHeight: this.avoidArea.topRectHeight })
          }
          .tabBar(this.tabBarBuilder('首页', 0, $r('app.media.ic_home_on'), $r('app.media.ic_home_off')))

          TabContent() {
            Mine({ onPageResume: this.onPageResume, statusBarHeight: this.avoidArea.topRectHeight })
          }.tabBar(this.tabBarBuilder('我的', 1, $r('app.media.ic_mine_on'), $r('app.media.ic_mine_off')))
        }
        .vertical(false)
        .divider({ strokeWidth: 0.5, color: '#0D182431' })
        .scrollable(false)
        .backgroundColor('#F1F3F5')

      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')//Navigation中的根布局背景色,也是安全区域会显示的颜色
      .padding({
        // top: this.avoidArea.topRectHeight + 'px'
        bottom: this.avoidArea.bottomRectHeight + 'px'//Tab内容显示在导航栏上面
      })

    }
    .mode(NavigationMode.Stack)
    .hideTitleBar(true)
    // .hideToolBar(true)
    .onNavBarStateChange((isVisible: boolean) => {
      //Navigation组件,根节点如何监听隐藏与展示,监听页面占中的显示和隐藏,上个页面返回的时候会触发,https://www.wzhi.top/?id=25
      console.info(`onNavBarStateChange isVisible=${isVisible}`)
      this.onPageResume = isVisible

      //页面可见和隐藏是需要设置安全区域
      if (isVisible) {
        this.onShown()
      } else {
        this.onHidden()
      }
    })
  }
}

 二、将Index.ets中获取的状态栏高度传入TabContent自定义组件设置顶部安全距离

这里以Home.ets为例

//网络请求
import { http } from '@kit.NetworkKit';
import { Banner, HomeArticle, HomeItemBean, HomeBean } from '../model/homeModel';
import { HomeNavigationTitle } from './HomeTitle';
import { request } from 'net_work'
import { HomeArticleView } from './HomeArticleView';
import List from '@ohos.util.List';


const getBanner = () => {
  return request<Array<Banner>>({
    url: "https://www.wanandroid.com/banner/json",
    method: http.RequestMethod.GET
  })
}

/**
 * 获取首页文章列表
 * 注意字符串中使用${}插入变量,需要使用`xxx${}x`
 * @param page 分页页码
 */
const getArticleList = (page: number) => {
  return request<HomeArticle>({
    url: `https://www.wanandroid.com/article/list/${page}/json`,
    method: http.RequestMethod.GET
  })
}

@Preview
@Component
export struct Home {
  @Consume indexPathStack: NavPathStack;

  //状态栏高度
  @Prop statusBarHeight: number

  /**
   * isRefreshing数据更新,会触发这个方法的调用
   */
  refreshStateChange() {
    ......
  }

  /**
   * 文章列表加载更多
   */
  articleLoadMore() {
    ......
  }

  @Builder
  HomeTitle() {
    HomeNavigationTitle()
  }

  /**
   * 页面创建生命收起函数
   */
  aboutToAppear(): void {
    this.getInitData()
  }

  /**
   * 获取初始化数据,banner和第一页文章列表
   */
  getInitData() {
    ......
  }

  build() {
    NavDestination() {
      Column() {
        //标题栏
        HomeNavigationTitle()
        //首页文章列表
        HomeArticleView({
          homeBean: this.homeBean,
          isRefreshing: this.isRefreshing,
          isLoadMore: this.isLoadMore,
          loadMoreState: this.loadMoreState
        })

      }.width('100%')
      .height('100%')
      .layoutWeight(1)
      .backgroundColor("#1296db")
      .padding({
        top: this.statusBarHeight + 'px'//设置顶部内容显示在状态栏下面
        // bottom: this.avoidArea.bottomRectHeight + 'px'
      })

    }
    .mode(NavDestinationMode.STANDARD)
    .hideTitleBar(true)
  }
}

完成的代码已经提交到gitee:WanHarmony: wanAndroid api 鸿蒙应用

HarmonyOS应用开发中,如果你希望应用不占用顶部状态栏,可以通过以下几种方法实现: 1. **在配置文件中设置**: 在`config.json`文件中设置`window`属性,添加`statusBar`配置项,设置为透明或不显示。 ```json { "app": { "bundleName": "com.example.myapp", "version": { "code": 1, "name": "1.0" } }, "deviceTypes": [ "phone" ], "module": { "mainAbility": { "abilities": [ { "name": "com.example.myapp.MainAbility", "icon": "$media:icon", "label": "MyApp", "window": { "statusBar": { "color": "#FFFFFF", "isVisible": false } } } ] } } } ``` 2. **在代码中设置**: 在`AbilitySlice`中通过`Window`对象来设置状态栏的可见性。 ```java import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Window; import ohos.agp.window.service.WindowManager; public class MainAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); setUIContent(ResourceTable.Layout_ability_main); Window window = getWindow(); WindowManager.LayoutParams attributes = window.getAttributes(); attributes.layoutConfig.fitWindow = true; attributes.layoutConfig.ignoreStatusBar = true; window.setAttributes(attributes); } } ``` 3. **使用主题设置**: 在`resources/base.json`文件中定义一个主题,并在主题中设置状态栏的样式。 ```json { "styles": [ { "name": "MyAppTheme", "parent": "android:Theme.Material.Light.NoActionBar", "window": { "statusBar": { "color": "#FFFFFF", "isVisible": false } } } ], "themes": [ { "name": "AppTheme", "parent": "MyAppTheme" } ] } ``` 通过以上几种方法,你可以控制HarmonyOS应用不占用顶部状态栏,从而实现更灵活的用户界面设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值