import { WindowHelper } from '../utils/WindowHelper'; import { inputMethod } from '@kit.IMEKit'; import { ToolsHelper } from '../utils/ToolsHelper'; export interface TitleBarBtn { text?: string | Resource; img?: PixelMap | ResourceStr | DrawableDescriptor; color?: string | Resource; onClick: () => void } @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 doubleBack: boolean // 是否显示浅色返回按钮 @Prop lightBack: boolean // 是否显示导航栏 @Prop hideNavBar: boolean /** * 是否显示左侧角标,存在onClickLeft时生效 */ @Prop showBadgeLeft: boolean; /** * 是否显示右侧角标,存在onClickLeft时生效 */ @Prop showBadgeRight: boolean; // 设置返回按钮事件,如果hideBack为true,该事件无效 onBackEvent?: () => void // 设置导航栏点击事件 @Prop onClickLeft: TitleBarBtn @Prop onClickRight: TitleBarBtn // 设置导航栏底下标题 @Prop bottomTitleText: ResourceStr @Builder doNothingBuilder() { } @BuilderParam customBuilderParam: () => void = this.doNothingBuilder build() { NavDestination() { Stack() { Column() { this.customBuilderParam() } .padding({ // 沉浸式直接0,如果给值的话,会造成用户ui无法覆盖状态栏 top: this.isImmersive ? 0 : this.hideNavBar ? 44 : WindowHelper.topRectHeight + 44, bottom: this.isImmersive ? 0 : WindowHelper.bottomRectHeight }) .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(this.lightBack ? $r("app.media.base_back_light") : $r("app.media.base_back")) .height(15) .objectFit(ImageFit.Contain).visibility(!this.hideBack ? Visibility.Visible : Visibility.None) }.width(110).height(44).alignItems(VerticalAlign.Center) .onClick(() => { if (this.hideBack) { return } if (this.onBackEvent && !this.hideBack) { this.onBackEvent() } else if (this.pageInfos) { this.pageInfos.pop() } }) Column() { Text(this.titleText ?? '') .maxLines(1) .fontColor(this.titleColor ?? '#11102C') .fontSize(16) .fontWeight(FontWeight.Medium) .ellipsisMode(EllipsisMode.CENTER) .textOverflow({ overflow: TextOverflow.Ellipsis }) .constraintSize({ maxWidth: 200 }) if (this.bottomTitleText) { Text(this.bottomTitleText ?? '').fontColor('#CB8204').fontSize(12).margin({ top: 4 }) } } Row() { if (!this.onClickLeft?.img && this.onClickLeft) { Badge({ count: this.showBadgeLeft ? 1 : 0, style: { badgeSize: 6, badgeColor: Color.Red, fontSize: 1, color: '#FF6500', } }) { 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', fontSize: 1 } }) { 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', fontSize: 1 } }) { 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', fontSize: 1 } }) { 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) { if (this.doubleBack) { const t = this.onBackEvent ToolsHelper.doubleAndExit(() => { t() }) } else { this.onBackEvent() } return true } else if (this.pageInfos) { if (this.doubleBack) { const t = this.pageInfos ToolsHelper.doubleAndExit(() => { t.pop() }) } else { this.pageInfos.pop() } return true } else { return false } }) } }