惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
J
Java Code Geeks
博客园 - 聂微东
B
Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
腾讯CDC
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Azure Blog
Microsoft Azure Blog
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
美团技术团队
博客园 - Franky
Google DeepMind News
Google DeepMind News
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
The Cloudflare Blog

人人都是产品经理

为什么你的产品找不到差异化?90%的失败都卡在第一步上(下) – 人人都是产品经理, 3年从30万到1300万用户、获2200万美元融资,这个AI教育产品用“抽卡”破解了获客难题 – 人人都是产品经理, 园区招商系统怎么做才能真正帮到去化?我加了这一个功能,推广链接转发400次阅读过万 – 人人都是产品经理, AI大事件:OpenAI发完网络安全模型又搞药物研发,小鹏汽车要抓”DeepSeek时刻” – 人人都是产品经理, 电商不是卖货,是一场更残酷的产品经理实战 – 人人都是产品经理, 没想到,活动营销又回来了! – 人人都是产品经理, 为何All-in海外KOC:一场关于AI时代窗口期的豪赌 – 人人都是产品经理, 重新理解企业的内部协作 – 人人都是产品经理, 苹果的 AI 战略到底是什么? – 人人都是产品经理, 医疗智能体·第2讲——合规护城河:等保、PIPL与HIPAA的架构实战 – 人人都是产品经理, 向量知识库五步法:从“答非所问”到“精准回复” – 人人都是产品经理, 鸿蒙PC三方库构建总指挥HPKBUILD(sha)库为例 – 人人都是产品经理, 何时该用LLM?AI产品经理的LLM设计指南 – 人人都是产品经理, 医疗信息领域的需求方、决策方、准入方以及关注点(二) – 人人都是产品经理, 即梦涨价:一场被误读的「傲慢」 – 人人都是产品经理, 面试AI PM必答题:Hermes和OpenClaw的区别,如何讲清楚业务价值 – 人人都是产品经理, AI的下一张船票:世界模型——AI产品经理必须理解的技术拐点 – 人人都是产品经理, 小红书做GEO,怎么让AI信你?记住这 3 个重要信息 – 人人都是产品经理, 5 家印度 AI 初创公司,看看印度 AI 再做什么 – 人人都是产品经理, AI项目跨团队协作:产品技术业务如何不打架 – 人人都是产品经理, Agentic Workflow(智能体工作流):让AI从”答案生成器”变成”数字员工” – 人人都是产品经理, lycium_plusplus 项目全景解读:OpenHarmony 三方库构建的“大管家” – 人人都是产品经理, 从爆单救火到前置履约:两套预采策略,把生鲜大促履约效率拉满 – 人人都是产品经理, 什么时候该补货?我用一轮数据做了一个决定 – 人人都是产品经理, 从“机械兜底”到“动态分流”:AI客服重复进线治理的4大底层逻辑 – 人人都是产品经理, 抖音拼效率,红书拼洞察 – 人人都是产品经理, 全民狂欢与退潮——为什么龙虾这波热潮冷却得如此之快? – 人人都是产品经理, Stripe押注!MPP重塑全球支付 – 人人都是产品经理, 小红书GEO:AI引用你的内容,不是因为你对,而是因为你看起来可信 – 人人都是产品经理, 前百度副总裁押注办公Agent,日韩付费爆发,Manus迎来强劲对手 – 人人都是产品经理,
window.setMainWindowOrientation 设置横竖屏切换,为什么没...
华为开发者联盟 · 2026-04-14 · via 人人都是产品经理

本问答帖原创发布在华为开发者联盟社区 ,欢迎开发者前往论坛提问交流。

更多与该问题相关的讨论,请点击原帖查看:

window.setMainWindowOrientation 设置横竖屏切换,为什么没有切换完成后的监听?-华为开发者问答 | 华为开发者联盟 (huawei.com)

问题描述:

window.setMainWindowOrientation 设置横竖屏切换,为什么没有切换完成后的监听?

解决方案:

【背景知识】

【解决方案】

import window from '@ohos.window';

import display from '@ohos.display';




const ORIENTATION: Array<string> = ['垂直', '平', '反向垂直', '反向水平']

@Entry

@Component

struct OrientationPage {

@State rotation: number = 0

@State message: string = ORIENTATION[this.rotation]

// 是否横屏状态

@State @Watch('setWindowLayOut') isLandscape: boolean = false;

aboutToAppear() {

// 监听屏幕状态改变

display.on("change", async () => {

// 获取当前旋转角度

this.rotation = await display.getDefaultDisplaySync().rotation

this.message = ORIENTATION[this.rotation]

});

}

setWindowLayOut() {

// 调用该接口手动改变设备横竖屏状态(设置全屏模式,先强制横屏,再加上传感器模式)

window.getLastWindow(getContext(this)).then((windowClass) => {

if (this.isLandscape) {

// 设置屏幕横屏

windowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);

} else {

// 设置屏幕竖屏

windowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION_PORTRAIT);

}

});

}

build() {

Row() {

Column() {

Text(`${this.rotation}`)

.fontSize(25)

Text(`${this.message}`)

.fontSize(25)

Button(this.isLandscape ? '竖屏' : '横屏')

.width(140)

.onClick(() => {

// 设置横屏

this.isLandscape = !this.isLandscape;

});

}

.width("100%")

}

.height('100%')

}

}
  • 可在EntryAbility的onWindowStageCreate中注册windowsSizeChange事件,并通过AppStorage存储,在页面中通过StorageLink监听数据的变换实现屏幕旋转的监听,可参考以下示例:
// EntryAbility.ets

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

import { hilog } from '@kit.PerformanceAnalysisKit';

import { display, window } from '@kit.ArkUI';




export default class EntryAbility extends UIAbility {

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');

}




onDestroy(): void {

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');

}




onWindowStageCreate(windowStage: window.WindowStage): void {




hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');




let mainWindow: window.Window;

try {

mainWindow = windowStage.getMainWindowSync();

let displayClass: display.Display = display.getDefaultDisplaySync();

AppStorage.setOrCreate('orientation', displayClass.orientation);

// 监听窗口的windowsSizeChange事件,旋转屏时会触发该事件

mainWindow.on('windowSizeChange', (data) => {

let displayClass: display.Display | null = null;

try {

displayClass = display.getDefaultDisplaySync();

// 获取屏幕的显示方向

AppStorage.set('orientation', displayClass.orientation);

} catch {

return;

}

})

} catch {

hilog.info(0x0000, 'testTag', '%{public}s', 'error');

return;

}




windowStage.loadContent('pages/Index', (err) => {

if (err.code) {

return;

}

hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');

});

}




onWindowStageDestroy(): void {

// Main window is destroyed, release UI related resources

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');

}




onForeground(): void {

// Ability has brought to foreground

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');

}




onBackground(): void {

// Ability has back to background

hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');

}

}




```

- 页面中通过StorageLink监听数据的变换实现屏幕旋转的监听:

```ts

// index.ets

import { display } from '@kit.ArkUI';




@Entry

@Component

struct Index {

// 获取通过监听窗口的windowsSizeChange事件得到的屏幕显示方向

@StorageLink('orientation') myOrientation: display.Orientation = 0;




build() {

Stack() {

// 当屏幕显示方向变化时,切换组件的视图效果

if (this.myOrientation == 0 ||

this.myOrientation == 2) {

Image($r('app.media.startIcon'))

.size({ width: 100, height: 100 })

.id('image1')

} else {

Image($r('app.media.background'))

.position({ x: 0, y: 0 })

.size({ width: 200, height: 200 })

.id('image2')

}

}

.backgroundColor(Color.White)

.size({ width: '100%', height: '100%' })

}

}

需要在项目的module.json5文件中的abilities列表里添加"orientation",指定为"auto_rotation":

{

"module": {

// ...

"abilities": [

{

// ...

"orientation": "auto_rotation",

}

],

}

}
  • 通过设备中的重力传感器,可以检测该设备在三个坐标轴(即X轴、Y轴及Z轴)上的线性加速度。基于这些数据,能够推算出屏幕当前的旋转状态。有关具体实现方式,可参考以下示例:
import sensor from '@ohos.sensor';

import base from '@ohos.base';

@Entry

@Component

struct OrientationPage {

@State rotation: string = 'INVALID'

onDegree(callback: base.Callback<string>): void {

sensor.on(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => {

let degree: number = -1;

degree = this.CalDegree(data.x, data.y, data.z)

console.log(degree + "zzz")

if (degree >= 0 && (degree <= 30 || degree >= 330)) {

this.rotation = "ROTATION_0";

} else if (degree >= 60 && degree <= 120) { // Use ROTATION_90 when degree range is [60, 120]

this.rotation = "ROTATION_90";

} else if (degree >= 150 && degree <= 210) { // Use ROTATION_180 when degree range is [150, 210]

this.rotation = "ROTATION_180";

} else if (degree >= 240 && degree <= 300) { // Use ROTATION_270 when degree range is [240, 300]

this.rotation = "ROTATION_270";

}

callback(this.rotation);

});

}

CalDegree(x: number, y: number, z: number): number {

let degree: number = -1;

// 3为有效_增量_角度_阈值_系数

if ((x * x + y * y) * 3 < z * z) {

return degree;

}

degree = 90 - (Number)(Math.round(Math.atan2(y, -x) / Math.PI * 180));

return degree >= 0 ? degree % 360 : degree % 360 + 360;

}

aboutToAppear() {

let callback = async (rotation: string) => {

console.log('rotation = ' + rotation)

}

try {

this.onDegree(callback);

} catch (exception) {

}

}

build() {

Row() {

Column() {

Text(`${this.rotation}`)

.fontSize(25)

}

.width("100%")

}

.height('100%')

}

}
  • 使用媒体查询接口监听屏幕旋转,设置媒体查询的查询条件为屏幕的方向,可选值为orientation:portrait(设备竖屏)和orientation: landscape(设备横屏)。有关具体实现方式,可参考以下示例:
import { mediaquery } from '@kit.ArkUI';

// 监听横屏事件

let listener = mediaquery.matchMediaSync('(orientation: portrait)');

function onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {

if (mediaQueryResult.matches) {

console.log(`横屏`)

} else {

}

}

// 注册回调

listener.on('change', onPortrait)

// 取消注册回调

listener.off('change', onPortrait)

【总结】

除可在module.json5文件中全局配置当前UIAbility组件启动时的方向之外,亦可通过调用window.setPreferredOrientation方法动态设定特定页面的窗口方向,请根据具体的业务场景选择合适的方案来监听屏幕旋转事件。

▶更多实践干货就在华为开发者联盟

▶扫码加入鸿蒙主题交流群,共同交流鸿蒙应用创新与开发