import { WindowHelper } from '../utils/WindowHelper'; import { inputMethod } from '@kit.IMEKit'; export interface TitleBarBtn { text?: string | Resource; img?: PixelMap | ResourceStr | DrawableDescriptor; color?: string | Resource; onClick: () => void } @Preview @Component export struct SafeView { pageInfos?: NavPathStack @Prop isLoading: boolean // 是不是沉浸式 @Prop isImmersive: boolean // 设置导航栏标题 @Prop titleText: ResourceStr // 设置导航栏标题颜色 @Prop titleColor: ResourceColor // 设置导航栏背景色 @Prop backgroundColorNav: ResourceColor // 设置导航栏背景色 @Prop backgroundColorView: ResourceColor // 设置导航栏背景不透明度 // 元素的不透明度,取值范围为0到1,1表示不透明,0表示完全透明, 达到隐藏组件效果,但是在布局中占位。 @Prop opacitys: number | Resource // 是否显示返回按钮 @Prop hideBack: boolean // 是否显示返回按钮 @Prop hideNavBar: boolean /** * 是否显示左侧角标,存在onClickLeft时生效 */ @Prop showBadgeLeft: boolean; /** * 是否显示右侧角标,存在onClickLeft时生效 */ @Prop showBadgeRight: boolean; // 设置返回按钮事件,如果hideBack为true,该事件无效 onBackEvent?: () => void = undefined // 设置返回按钮事件 onClickLeft?: TitleBarBtn onClickRight?: TitleBarBtn @Builder doNothingBuilder() { } @BuilderParam customBuilderParam: () => void = this.doNothingBuilder build() { NavDestination() { Stack() { Column() { this.customBuilderParam() } .padding({ top: this.isImmersive ? 0 : WindowHelper.topRectHeight + 44 }) .align(Alignment.Top) .width('100%') .height('100%') if (!this.hideNavBar) { Row() .height(WindowHelper.topRectHeight) .width('100%') .backgroundColor(this.backgroundColorNav ?? '#ffffff') .opacity(undefined === this.opacitys ? 1 : this.opacitys > 1 ? 1 : this.opacitys < 0 ? 0 : this.opacitys) Row() { Row() { Image($r("app.media.base_back")) .height(15) .objectFit(ImageFit.Contain).visibility(!this.hideBack ? Visibility.Visible : Visibility.None) }.width(110) .onClick(() => { if (this.hideBack) { return } if (this.onBackEvent && !this.hideBack) { this.onBackEvent() } else if (this.pageInfos) { this.pageInfos.pop() } }) Text(this.titleText ?? '') .maxLines(1) .fontColor(this.titleColor ?? '#11102C') .fontSize(16) .fontWeight(FontWeight.Medium) .ellipsisMode(EllipsisMode.CENTER) .textOverflow({ overflow: TextOverflow.Ellipsis }) .constraintSize({ maxWidth: 200 }) Row() { if (!this.onClickLeft?.img && this.onClickLeft) { Badge({ count: this.showBadgeLeft ? 1 : 0, style: { badgeSize: 6, badgeColor: Color.Red } }) { Text(`${this.onClickLeft?.text}` ?? '确定') .fontColor(this.onClickLeft?.color ?? '#17171A') .onClick(() => { this.onClickLeft?.onClick && this.onClickLeft?.onClick() }) } } if (this.onClickLeft?.img && this.onClickLeft) { Badge({ count: this.showBadgeLeft ? 1 : 0, style: { badgeSize: 6, badgeColor: '#FF6500', color: '#FF6500' } }) { Image(this.onClickLeft.img) .onClick(() => { this.onClickLeft?.onClick && this.onClickLeft?.onClick() }) .objectFit(ImageFit.Contain) .width(20) .height(20) } } if (!this.onClickRight?.img && this.onClickRight) { Badge({ count: this.showBadgeRight ? 1 : 0, style: { badgeSize: 6, badgeColor: '#FF6500', color: '#FF6500' } }) { Text(this.onClickRight?.text ?? '确定') .fontColor(this.onClickRight?.color ?? '#17171A') .onClick(() => { this.onClickRight?.onClick && this.onClickRight?.onClick() }) .margin({ left: 10 }) } } if (this.onClickRight?.img && this.onClickRight) { Badge({ count: this.showBadgeRight ? 1 : 0, style: { badgeSize: 6, badgeColor: '#FF6500', color: '#FF6500' } }) { Image(this.onClickRight.img) .onClick(() => { this.onClickRight?.onClick && this.onClickRight?.onClick() }) .objectFit(ImageFit.Contain) .width(20) .height(20) .margin({ left: 10 }) } } }.width(110) .justifyContent(FlexAlign.End) } .backgroundColor(this.backgroundColorNav ?? '#ffffff') .opacity(undefined === this.opacitys ? 1 : this.opacitys > 1 ? 1 : this.opacitys < 0 ? 0 : this.opacitys) .justifyContent(FlexAlign.SpaceBetween) .height(44) .padding({ left: 15, right: 15 }) .width('100%') .margin({ top: WindowHelper.topRectHeight }) } Column() { LoadingProgress() .color(Color.White) .width(80).height(80) Text('努力加载中..') .fontSize(16) .fontColor(Color.White) } .visibility(this.isLoading ? Visibility.Visible : Visibility.None) .width('100%') .height('100%') .backgroundColor('#40000000') .justifyContent(FlexAlign.Center) } .align(Alignment.Top) .width('100%') .height('100%') } .onClick(() => { inputMethod.getController().stopInputSession() }) .hideTitleBar(true) .width('100%') .height('100%') .backgroundColor(this.backgroundColorView ?? '#ffffff') .onBackPressed(() => { if (this.onBackEvent) { this.onBackEvent() return true } else if (this.pageInfos) { this.pageInfos.pop() return true } else { return false } }) } }