1 效果简述
在播放视频软件中,会有点击按钮后竖屏播放切换为横屏播放的功能,过程中附带应用旋转的效果。本文以demo形式展示HarmonyOS Next的实现。
2 实现原理
实现的基本步骤为,在点击按钮后,通过窗口的setPreferredOrientation接口设置应用窗口window的orientation为横屏,此时系统侧会更改窗口宽高,这时只需要监听窗口的windowSizeChange事件,在回调中更改页面布局即可。
其中orientation的枚举值为:
开发过程中,需要横屏时,将window的orientation设置为LANDSCAPE_INVERTED,竖屏时设为PORTRAIT。
3 代码实现
由于需要操作应用的窗口属性,因此需要首先获取应用的window对象:
3.1 获取应用的窗口window对象
需要在EntryAbility.ets中的onWindowStageCreate生命周期中,保存窗口对象以备后续使用:
修改内容为下述代码的第6-7行:
ts
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
// 先通过getMainwWindowSync获取window,再保存到数据结构中
let window = windowStage.getMainWindowSync();
MyWindowUtil.setWindow(window);
windowStage.loadContent('pages/Index', (err, data) => {
对应的MyWindowUtil类型定义为:
ts
import window from '@ohos.window'
export class MyWindowUtil {
private static window: window.Window;
public static setWindow(window: window.Window): void {
this.window = window;
}
public static getWindow(): window.Window {
return this.window;
}
}
3.2 在界面中添加触发旋转屏逻辑并监听windowSizeChange尺寸变化
ts
import window from '@ohos.window';
import { BusinessError } from '@ohos.base';
import { MyWindowUtil } from '../common/MyWindowUtil';
@Entry
@Component
struct Index {
@State widthValue: number = 200;
@State heightValue: number = 100;
private isLandScape: boolean = false;
aboutToAppear(): void {
// aboutToAppear中监听窗口尺寸变化,在回调中改变页面内容的布局以适配横屏
try {
MyWindowUtil.getWindow().on('windowSizeChange', (data) => {
if (data.width > data.height) {
this.widthValue = 300;
this.heightValue = 200;
} else {
this.widthValue = 200;
this.heightValue = 100;
}
})
} catch (exception) {
console.log('register windowSizeChange failed ' + JSON.stringify(exception));
}
}
build() {
Stack() {
Image($r('app.media.spring'))
.size({ width: this.widthValue, height: this.heightValue })
}
.size({ width: '100%', height: '100%' })
.onClick(() => {
let orientation = this.isLandScape ? window.Orientation.PORTRAIT : window.Orientation.LANDSCAPE_INVERTED;
this.isLandScape = !this.isLandScape;
try {
// 点击界面,设置窗口的orientation
MyWindowUtil.getWindow().setPreferredOrientation(orientation, (err: BusinessError) => {
console.info('onClick, businessError ' + JSON.stringify(err));
})
} catch (exception) {
console.info('onClick, exception ' + JSON.stringify(exception));
}
})
}
}
效果(在RK3568开发板上的效果):