场景一:静态页面或视频播放页面在平板横竖屏切换时卡顿,不够流畅。
场景二:在页面aboutToAppear中调用setPreferredOrientation设置横屏,在aboutToDisappear中设置竖屏,横竖屏切换时感官上出现卡顿。
场景一:
场景二:
在横屏页面的aboutToAppear方法中调用setPreferredOrientation设置横屏,在aboutToDisappear方法中设置竖屏。由于方向设置在页面生命周期回调中执行,页面转场与方向旋转存在时间差,导致感官上出现卡顿。
场景一:
场景二:
在aboutToAppear和aboutToDisappear中调用setPreferredOrientation设置屏幕方向时,方向切换与页面转场动画不同步,页面先完成转场再触发方向旋转,导致视觉上出现卡顿。该问题不属于性能问题,而是方向设置时机不当导致的功能故障。
场景一:
场景二:
通过NavDestination的preferredOrientation属性声明式设置页面方向,配合customTransition添加转场动画,使方向切换与页面转场同步进行,改善视觉卡顿。
示例代码如下:
import { LandscapePage } from './LandscapePage';
import { PortraitPage } from './PortraitPage';
@Entry
@Component
struct ExamplePage {
private stack: NavPathStack = new NavPathStack();
aboutToAppear(): void {
this.stack.pushPath({ name: "portrait" });
}
@Builder
MyPageMap(name: string) {
if (name === 'portrait') {
PortraitPage();
} else {
LandscapePage();
}
}
build() {
Navigation(this.stack) {
}
.width('100%')
.height('100%')
.hideNavBar(true)
.navDestination(this.MyPageMap)
}
} import { window } from '@kit.ArkUI';
@Component
export struct PortraitPage {
private info: string = '';
private stack: NavPathStack | undefined = undefined;
build() {
NavDestination() {
Stack({ alignContent: Alignment.Center }) {
Button('push LANDSCAPE page').onClick(() => {
this.stack?.pushPath({ name: 'landscape' }, true);
})
}.width('100%').height('100%')
}
.width('100%').height('100%')
.title('竖屏页面')
.preferredOrientation(window.Orientation.PORTRAIT)
.backgroundColor(Color.White)
.onResult((result: ESObject) => {
if (result !== null && typeof result === 'string') {
this.info = result;
}
})
.onReady((ctx: NavDestinationContext) => {
this.stack = ctx.pathStack;
})
}
} import { window } from '@kit.ArkUI';
type voidFunc = () => void;
@Component
export struct LandscapePage {
private stack: NavPathStack | undefined = undefined;
@State rotateAngle: string = '0deg';
@State currentOpacity: number = 1;
build() {
NavDestination() {
Stack({ alignContent: Alignment.Center }) {
Button('push PORTRAIT page').onClick(() => {
this.stack?.pushPath({ name: 'portrait' });
})
}.width('100%').height('100%')
}
.width('100%').height('100%')
.title('横屏页面')
.preferredOrientation(window.Orientation.LANDSCAPE)
.backgroundColor(Color.White)
.opacity(this.currentOpacity)
.ignoreLayoutSafeArea([LayoutSafeAreaType.SYSTEM], [LayoutSafeAreaEdge.TOP, LayoutSafeAreaEdge.BOTTOM])
.onReady((ctx: NavDestinationContext) => {
this.stack = ctx.pathStack;
})
.rotate({ angle: this.rotateAngle })
.customTransition(
(op: NavigationOperation, isEnter: boolean): Array<NavDestinationTransition> | undefined => {
const TRANSITION_DURATION: number = 300;
const ANGLE_DEFAULT: string = '0deg';
const ANGLE_TILT: string = '-30deg';
let transitionOneEvent: voidFunc | undefined = undefined;
if (op === NavigationOperation.PUSH) {
if (isEnter) {
this.currentOpacity = 0;
this.rotateAngle = ANGLE_TILT;
transitionOneEvent = () => {
this.rotateAngle = ANGLE_DEFAULT;
this.currentOpacity = 1;
}
} else {
this.currentOpacity = 0;
}
} else if (op === NavigationOperation.POP) {
if (isEnter) {
this.rotateAngle = ANGLE_DEFAULT;
} else {
this.currentOpacity = 1;
transitionOneEvent = () => {
this.rotateAngle = ANGLE_TILT;
this.currentOpacity = 0;
}
}
}
if (transitionOneEvent === undefined) {
return undefined;
}
let transitionOne: NavDestinationTransition = {
duration: TRANSITION_DURATION,
delay: 0,
curve: Curve.EaseOut,
event: transitionOneEvent,
onTransitionEnd: () => {}
};
return [transitionOne];
})
}
}