HarmonyOS 鸿蒙Next 路由页面跳转,可否实现转场时设置背景透明,而不是白屏
HarmonyOS 鸿蒙Next 路由页面跳转,可否实现转场时设置背景透明,而不是白屏
【关键字】
页面跳转 / 自定义组件
【问题描述】
路由页面跳转,可否实现转场时设置背景透明,而不是白屏
具体开发场景如下:
从页面A通过路由push到页面B,页面B可以通过下拉关闭,但是此时下拉的时候设置translate-y整体布局向下滑动,但是上部分布局是白色的,而不是可以观察到上次页面A的内容,发现是转场造成的。
目前通过设置页面A的PageTransitionExit({ type: RouteType.Push, duration: 999999999 }) ,给与页面A在退出的时候时长给与很长的时间,从未间接实现B页面向下拖动位移可以展示页面A的内容,从而避免白屏。但是问题是如果从页面B push跳转到页面C,再从页面C返回到页面B,再下拉又是白屏。
目前没有统一对路由跳转样式的处理,需要对所有可能打开可滑动关闭的路由页面都要在pageTransition()里面添加 PageTransitionExit({ type: RouteType.Push, duration: 9999999 }) 设置。
具体实现效果情况如下:
从主页面跳转到播放页,下拉可展示主页面的视图,再从播放页跳转到专辑详情再返回,下拉又变白屏。
问题点:
虽然也可以通过模拟转场全屏转场实现该功能,但是转场是附加在UI上的行为,不可能所有涉及到该跳转都要添加,而且模拟转场通过push打开别的页面该模拟转场会自动关闭,不符合需求场景。
【解决方案】
播放页面使用自定义组件可以实现您要的效果。即主页面加载播放页面组件,播放页面非Page而是Component,通过手势控制播放页面组件关闭。
示例代码如下:
// Index.ets import router from ‘@ohos.router’
@Entry @Component struct Index { @State panelPosition: VerticalAlign = VerticalAlign.Bottom @State openComment: boolean = false
build() { Column() { RelativeContainer() { Row() { Button(“打开页面B”).onClick(() => { this.openComment = true animateTo({ duration: 500 }, () => { this.panelPosition = VerticalAlign.Top }) }) } .width(“100%”) .height(“30%”) .offset({ x: 0, y:0 }) .alignRules({ top: { anchor: ‘container’, align: VerticalAlign.Top }, //以父容器为锚点,竖直方向顶头对齐 middle: { anchor: ‘container’, align: HorizontalAlign.Center } //以父容器为锚点,水平方向居中对齐 }) .id(‘row1’) //设置锚点为row1
if (this.openComment) { PageB({ panelPosition: this.panelPosition, openComment: this.openComment }) .alignRules({ left: { anchor: “container”, align: HorizontalAlign.Start }, top: { anchor: “container”, align: this.panelPosition } }) .id(“customPanel”) } } .width(“100%”).height(“100%”) .backgroundColor(Color.Pink) } .height(‘100%’).width(“100%”) } }
@Component struct PageB { @State panelHeight: string = “100%” @State textInputValue: string = “” @Link panelPosition: VerticalAlign @Link openComment: boolean private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Down }) private mOnTouchDownTime: number = 0 @State offsetY: number = 0 @State positionY: number = 0
build() { Column() {
Button(‘打开PageOne’) .fontSize(50) .margin({ top:30 }) .fontWeight(FontWeight.Bold) .onClick(() => { router.pushUrl({ //TODO 改为实际使用的url url:‘pages/PageOne’ }) })
} .width(“100%”) .height(this.panelHeight) .backgroundColor(Color.White) .translate({ x: 0, y: this.offsetY, z: 0 }) .gesture( PanGesture(this.panOption) .onActionStart(() => { this.mOnTouchDownTime = Date.now() }) .onActionUpdate((event?: GestureEvent) => { if (event) { this.offsetY = this.positionY + event.offsetY } }) .onActionEnd(() => { //计算下速度 let speed = Math.abs(this.offsetY / (Date.now() - this.mOnTouchDownTime))
if(this.offsetY > 200 || speed > 1.9){ animateTo({ duration: 500, onFinish: () => { this.openComment = false } }, () => { this.panelPosition = VerticalAlign.Bottom }) } else{ animateTo({ duration: 500, onFinish: () => { this.openComment = true } }, () => { this.offsetY = 0 this.panelPosition = VerticalAlign.Top }) } }) ) } }