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
})
}
})
)
}
}