状态栏的修改和沉浸式可以参考官方文档: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 鸿蒙应用