欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > [Harmony]自定义导航栏

[Harmony]自定义导航栏

2025/7/5 19:25:35 来源:https://blog.csdn.net/u012881779/article/details/148104436  浏览:    关键词:[Harmony]自定义导航栏

1.方案一

CustomNavigationBar


import { router } from '@kit.ArkUI';
import { DevicesUtil } from '../utils/DevicesUtil';
import { common } from '@kit.AbilityKit';@Component
export struct CustomNavigationBar {@State private navHeight: number = 44@State parTitle: string = ''@State parBGColor: Color = Color.Whiteprivate context = getContext(this) as common.UIAbilityContext;onHeightChange?: (height: number) => voidaboutToAppear() {DevicesUtil.getStatusBarHeight(this.context).then(height => {this.onHeightChange?.(height + this.navHeight) // 触发回调})}build() {Column({ space:0 }) {Stack(){Row({ space: 0 }) {Image($r('app.media.icon_base_back')).objectFit(ImageFit.Contain).width(44).height(44).padding(12).onClick(() => router.back())Image($r('app.media.icon_nav_logo')).objectFit(ImageFit.Contain).width(64).height(44).padding({ right: 10 })}.width('100%').justifyContent(FlexAlign.SpaceBetween).backgroundColor(Color.Transparent)Row({ space: 0 }) {Text(this.parTitle).fontSize(17).fontColor($r('app.color.mf_base_333333')).fontWeight(FontWeight.Bold)}.justifyContent(FlexAlign.Center).backgroundColor(Color.Transparent)}.width('100%').height(this.navHeight)}.width('100%').backgroundColor(this.parBGColor).expandSafeArea( [SafeAreaType.SYSTEM], [SafeAreaEdge.TOP] )}}

示意图

2.方案二

CustomNavigationBar


import { router, window } from '@kit.ArkUI';
import { DevicesUtil } from '../utils/DevicesUtil';
import { common } from '@kit.AbilityKit';@Component
export struct CustomNavigationBar {@State private statusBarHeight: number = 24 // 默认值(vp)@State private navHeight: number = 44@State parTitle: string = ''@State parBGColor: Color = Color.Whiteprivate context = getContext(this) as common.UIAbilityContext;onHeightChange?: (height: number) => voidaboutToAppear() {DevicesUtil.getStatusBarHeight(this.context).then(height => {this.statusBarHeight = heightthis.onHeightChange?.(height + this.navHeight) // 触发回调})}build() {Column({ space:0 }) {// 状态栏占位区域Row().width('100%').height(this.statusBarHeight).backgroundColor(Color.Transparent)// 导航内容区域Stack(){Row({ space: 0 }) {Image($r('app.media.icon_base_back')).objectFit(ImageFit.Contain).width(44).height(44).padding(12).onClick(() => router.back())Image($r('app.media.icon_nav_logo')).objectFit(ImageFit.Contain).width(64).height(44).padding({ right: 10 })}.width('100%').justifyContent(FlexAlign.SpaceBetween).backgroundColor(Color.Transparent)Row({ space: 0 }) {Text(this.parTitle).fontSize(17).fontColor($r('app.color.mf_base_333333')).fontWeight(FontWeight.Bold)}.justifyContent(FlexAlign.Center).backgroundColor(Color.Transparent)}.width('100%').height(this.navHeight)}.width('100%').backgroundColor(this.parBGColor).expandSafeArea( [SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM] ).onAppear(async ()=>{window.getLastWindow(this.context).then(win => {win.setWindowLayoutFullScreen(true) // 隐藏系统栏// win.setWindowSystemBarEnable(['navigation']) // 可选控制导航栏显示//这一句不设置 不然第二次进入是就没状态栏那一行了})})}}

示意图

3.工具

获取状态栏高度

import window from '@ohos.window';
import { common } from '@kit.AbilityKit';export class DevicesUtil {/// 状态栏高度static async getStatusBarHeight(context: common.UIAbilityContext, isVP: boolean = true): Promise<number> {try {const win = await window.getLastWindow(context);/*getWindowAvoidArea返回的物理像素,需要转换为虚拟像素返回,便于布局TYPE_SYSTEM:获取状态栏区域(推荐使用)TYPE_NAVIGATION_INDICATOR:获取导航栏区域TYPE_CUTOUT:获取刘海屏区域*/const avoidArea = await win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);if (isVP) {return DevicesUtil.pxToVp(avoidArea.topRect.height);} else {return avoidArea.topRect.height;}} catch {return isVP ? 24 : 96; // 默认安全高度 // 96 假设480dpi设备}}
}

4.使用示例

跳转协议

/// 用户隐私协议
private userPrivacyPolicy() {router.pushUrl({url: 'pages/features/protocol/MFProtocolView',params: {webUrl: 'https://www.baidu.com',title: '隐私协议'}})
}

协议页面

注意:方案二会导致页面底部超出屏幕,所以需要设置.margin({bottom: this.navHeight})

import { router } from '@kit.ArkUI';
import { webview } from '@kit.ArkWeb';
import { CustomNavigationBar } from '../../../support/custom/CustomNavigationBar';
import ConsoleLog from '../../../support/extension/ConsoleLog';interface MFProtocolParams {webUrl: string;title?: string;
}@Entry
@Component
struct MFProtocolView {@State webUrl: string = ''; // 接收的网页地址@State title: string = '详情'; // 导航栏标题private controller: webview.WebviewController = new webview.WebviewController();@State private navHeight: number = 68 // 默认值(vp)aboutToAppear() {// 在aboutToAppear生命周期中读取路由参数const params: MFProtocolParams = router.getParams() as MFProtocolParams;if (params) {this.webUrl = params.webUrl || 'about:blank'; // 默认为空页面this.title = params.title || this.title; // 默认为'协议详情'}}build() {Column() {// 使用自定义导航栏组件CustomNavigationBar({ parTitle: this.title, parBGColor: Color.Red, onHeightChange: (height)=>{this.navHeight = height}})// 必须传递完整WebOptions参数Web({src: this.webUrl,controller: this.controller}).flexGrow(1) // 自动填充剩余空间.margin({bottom: this.navHeight}) // 方案一不用这行代码,方案二需要这行.onPageBegin((event) => {ConsoleLog.log('开始加载:' + event.url);})}.width('100%').height('100%').backgroundColor(Color.Green).onAppear(()=>{})}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词