场景描述
在HarmonyOS移动应用开发中,横竖屏旋转适配成为了一个不可或缺的功能点。特别是在HarmonyOS NEXT平台,开发者面临着更加多样化的设备和更复杂的用户交互需求。以下是我们在项目中遇到的一些关于横竖屏旋转的高频问题及解决方案:
- 如何通过传感器自己感知方向并设置旋转:在不考虑设备是否启用了系统自带的旋转锁定的情况下,如何利用传感器来检测设备方向,并据此调整应用的显示方向。
- 同一应用内不同页面的不同旋转策略:例如,首页只支持竖屏显示,而详情页则支持横竖屏自由切换。
概念说明
- 旋转策略:指当前页面支持的设备旋转方向。
- 页面方向:指手机页面当前的显示方向。
场景一:通过传感器感知方向并设置旋转
关键步骤
- 感知方向:使用
sensor
模块中的重力传感器(GRAVITY
)来获取设备的真实朝向。
import sensor from '@ohos.sensor';
// 注册重力传感器事件
sensor.on(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => {
let degree: number = -1;
let rotation: string = 'INVALID';
// 计算角度
function CalDegree(x: number, y: number, z: number): number {
return Math.round(Math.atan2(y, x) * (180 / Math.PI));
}
degree = CalDegree(data.x, data.y, data.z);
// 根据角度确定旋转方向
if (degree >= 0 && (degree <= 30 || degree >= 330)) {
rotation = "ROTATION_0";
} else if (degree >= 60 && degree <= 120) {
rotation = "ROTATION_90";
} else if (degree >= 150 && degree <= 210) {
rotation = "ROTATION_180";
} else if (degree >= 240 && degree <= 300) {
rotation = "ROTATION_270";
}
// 设置窗口的显示方向
if (rotation !== 'INVALID') {
window(getContext(this)).then((win) => {
win.setPreferredOrientation(rotation);
});
}
});
- 设置旋转:通过
window
模块提供的setPreferredOrientation
方法来设置窗口的显示方向。
场景二:同一应用内不同页面的不同旋转策略
关键步骤
- 注册无感监听:在应用启动时,注册一个全局监听器来监听页面的生命周期变化。
- 建立页面与旋转方向的映射表:定义一个映射表,用于存储每个页面对应的旋转方向。
const pageOrientations: Record<string, window.Orientation> = {
"Logon": window.Orientation.PORTRAIT,
"Detail": window.Orientation.LANDSCAPE,
"Page2": window.Orientation.PORTRAIT_INVERTED,
"Page3": window.Orientation.LANDSCAPE_INVERTED,
};
- 控制旋转策略:当页面发生变化时,根据映射表来调整页面的旋转方向。
import window from '@ohos.window';
// 监听页面生命周期变化
function trackPageLifecycle(windowName: string, lifecycleEvent: any) {
const win = window.getLastWindow(getContext(this));
const pageName = lifecycleEvent.name; // 假设此为页面名称
// 根据页面名称设置旋转方向
win.setPreferredOrientation(pageOrientations[pageName]);
}
// 初始化监听
function initPageTracking() {
const observer = window.createWindowObserver();
observer.on('pageShow', (info) => trackPageLifecycle(info.windowName, info));
observer.on('pageHide', (info) => trackPageLifecycle(info.windowName, info));
}
initPageTracking();
场景三:视频播放过程中的临时方向设置
对于视频播放等特定场景,可能需要提供一种临时改变屏幕方向的方式,而不会影响整体的应用旋转策略。
window.getLastWindow(getContext(this), (err, win) => {
if (err) {
console.error("Failed to get last window", err);
return;
}
win.setPreferredOrientation(window.Orientation.USER_ROTATION_LANDSCAPE);
});
其他常见问题
Q: 如何感知系统的自动旋转开关状态?
A: 可以通过sensor
模块监听设备方向的变化,同时使用settings
模块查询系统的自动旋转开关状态。
import settings from '@ohos.settings';
// 查询自动旋转开关状态
const isAutoRotationEnabled = settings.getValueSync(getContext(), settings.general.ACCELEROMETER_ROTATION_STATUS, '-1') === '1';
console.log("Auto Rotation is " + (isAutoRotationEnabled ? "enabled" : "disabled"));
// 获取当前设备的方向
const currentOrientation = settings.getValueSync(getContext(), settings.display.DEFAULT_SCREEN_ROTATION, '-1');
console.log("Current screen rotation: " + currentOrientation);