HarmonyOS开发中的显示设置全解析
HarmonyOS APP开发中的显示设置全解析:从亮度调节到折叠屏适配,掌控每一块屏幕
📌 核心要点:HarmonyOS 提供完整的显示设置 API,涵盖亮度、方向、超时、分辨率和折叠屏适配,让应用在不同设备上都有最佳视觉体验
一、背景与动机
你有没有这样的体验——晚上躺在床上刷手机,屏幕亮得像探照灯,刺得眼睛生疼;或者看电子书时,屏幕突然自己转了方向,文字全歪了;又或者手机放在桌上忘了锁屏,回来一看电量掉了一半……
这些都是显示设置要解决的问题。作为开发者,我们不仅要让应用"能用",还要让它在各种显示环境下都"好用"——该亮的时候亮,该暗的时候暗,该横的时候横,该竖的时候竖。
HarmonyOS 的 @ohos.display 模块提供了全面的显示控制能力。从最基础的亮度调节,到复杂的折叠屏适配,它都能搞定。
典型使用场景:
- 阅读器:根据环境光自动调节亮度,阅读时锁定竖屏
- 视频播放器:播放时切换横屏、保持常亮
- 导航应用:全程保持屏幕常亮,避免息屏
- 折叠屏应用:展开时显示平板布局,折叠时显示手机布局
二、核心原理
2.1 显示设置体系架构

flowchart TB
A[应用层] --> B[显示设置管理]
B --> C[屏幕亮度]
B --> D[屏幕方向]
B --> E[屏幕超时]
B --> F[分辨率/刷新率]
B --> G[折叠屏适配]
C --> C1[系统亮度值]
C --> C2[自动亮度]
C --> C3[窗口亮度覆盖]
D --> D1[竖屏/横屏]
D --> D2[方向锁定]
D --> D3[传感器跟随]
E --> E1[休眠超时]
E --> E2[保持常亮]
F --> F1[分辨率切换]
F --> F2[高刷新率]
G --> G1[折叠状态监听]
G --> G2[布局自适应]
G --> G3[窗口尺寸变化]
classDef primary fill:#4CAF50,stroke:#388E3C,color:#fff
classDef warning fill:#FF9800,stroke:#F57C00,color:#fff
classDef error fill:#F44336,stroke:#D32F2F,color:#fff
classDef info fill:#2196F3,stroke:#1976D2,color:#fff
classDef purple fill:#9C27B0,stroke:#7B1FA2,color:#fff
class A primary
class B info
class C,D,E,F,G warning
class C1,C2,C3,D1,D2,D3,E1,E2,F1,F2,G1,G2,G3 purple
2.2 核心模块与 API
| 模块 | 核心 API | 说明 |
|---|---|---|
@ohos.display |
getDefaultDisplaySync() |
获取默认屏幕信息 |
@ohos.display |
on('foldStatusChange') |
监听折叠状态变化 |
@ohos.display |
on('displaySizeChange') |
监听屏幕尺寸变化 |
@ohos.window |
setWindowBrightness() |
设置窗口亮度 |
@ohos.window |
setPreferredOrientation() |
设置屏幕方向 |
@ohos.window |
setWindowKeepScreenOn() |
设置保持常亮 |
2.3 亮度控制层级
flowchart LR
A[系统全局亮度] -->|0~255| B[亮度值]
C[自动亮度开关] -->|开/关| B
D[窗口亮度覆盖] -->|0~1.0| E[当前窗口亮度]
B -->|基础值| E
classDef primary fill:#4CAF50,stroke:#388E3C,color:#fff
classDef warning fill:#FF9800,stroke:#F57C00,color:#fff
classDef error fill:#F44336,stroke:#D32F2F,color:#fff
classDef info fill:#2196F3,stroke:#1976D2,color:#fff
classDef purple fill:#9C27B0,stroke:#7B1FA2,color:#fff
class A primary
class C warning
class D info
class E primary
关键理解:窗口亮度是覆盖系统亮度的。就像你在灯光通明的房间里又开了一盏台灯——台灯的亮度只影响你桌面的区域,不影响整个房间。同理,窗口亮度只影响当前应用窗口,退出应用后恢复系统亮度。
三、代码实战
3.1 屏幕亮度调节:阅读器的护眼模式
阅读器对亮度的要求很特殊——不能太亮刺眼,也不能太暗看不清。最佳方案是跟随系统自动亮度,同时允许用户微调。
import { window } from '@kit.ArkUI';
import { display } from '@kit.ArkUI';
/**
* 亮度管理器
* 封装屏幕亮度相关操作
*/
class BrightnessManager {
private mainWindow: window.Window | null = null;
/**
* 初始化,获取主窗口
*/
async init(context: Context): Promise<void> {
const windowStage = window.findWindow('MainWindow');
if (windowStage) {
this.mainWindow = windowStage;
} else {
// 通过 context 获取窗口
this.mainWindow = await window.getLastWindow(context);
}
}
/**
* 设置窗口亮度(0.0 ~ 1.0)
* 只影响当前窗口,不影响系统亮度
* @param brightness 亮度值,0.0 最暗,1.0 最亮
*/
async setWindowBrightness(brightness: number): Promise<void> {
if (!this.mainWindow) {
console.error('[Brightness] 窗口未初始化');
return;
}
// 限制范围
const clamped = Math.max(0, Math.min(1, brightness));
try {
await this.mainWindow.setWindowBrightness(clamped);
console.info(`[Brightness] 窗口亮度设置: ${clamped}`);
} catch (err) {
console.error(`[Brightness] 设置失败: ${JSON.stringify(err)}`);
}
}
/**
* 获取当前窗口亮度
*/
async getWindowBrightness(): Promise<number> {
if (!this.mainWindow) return -1;
try {
const properties = await this.mainWindow.getWindowProperties();
return properties.brightness;
} catch (err) {
console.error(`[Brightness] 获取失败: ${JSON.stringify(err)}`);
return -1;
}
}
/**
* 重置窗口亮度为系统默认
* 传入 -1 表示跟随系统
*/
async resetWindowBrightness(): Promise<void> {
if (!this.mainWindow) return;
try {
await this.mainWindow.setWindowBrightness(-1);
console.info('[Brightness] 已重置为系统亮度');
} catch (err) {
console.error(`[Brightness] 重置失败: ${JSON.stringify(err)}`);
}
}
/**
* 获取系统屏幕亮度(0 ~ 255)
*/
getSystemBrightness(): number {
try {
const displayInfo = display.getDefaultDisplaySync();
// 通过 display 获取亮度需要系统 API 权限
// 普通应用建议使用窗口亮度覆盖
return 128; // 默认值
} catch (err) {
return 128;
}
}
}
/**
* 阅读器亮度控制页面
*/
@Entry
@Component
struct ReaderBrightnessPage {
@State currentBrightness: number = 0.5;
@State isFollowSystem: boolean = true;
private brightnessManager: BrightnessManager = new BrightnessManager();
async aboutToAppear(): Promise<void> {
const context = getContext(this);
await this.brightnessManager.init(context);
// 读取当前窗口亮度
const brightness = await this.brightnessManager.getWindowBrightness();
if (brightness >= 0) {
this.currentBrightness = brightness;
this.isFollowSystem = brightness < 0; // -1 表示跟随系统
}
}
build() {
Column() {
// 标题
Text('阅读亮度设置')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 24 })
// 亮度预览区域
Column() {
Text('这是一段示例文字,用于预览当前亮度效果。')
.fontSize(16)
.lineHeight(28)
.padding(20)
}
.width('100%')
.height(200)
.backgroundColor('#FFF8E1')
.borderRadius(16)
.justifyContent(FlexAlign.Center)
.margin({ bottom: 24 })
// 跟随系统开关
Row() {
Text('跟随系统亮度')
.fontSize(16)
.layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.isFollowSystem })
.onChange(async (isOn: boolean) => {
this.isFollowSystem = isOn;
if (isOn) {
await this.brightnessManager.resetWindowBrightness();
} else {
await this.brightnessManager.setWindowBrightness(this.currentBrightness);
}
})
}
.width('100%')
.padding({ left: 16, right: 16 })
.margin({ bottom: 20 })
// 亮度滑块
Column() {
Row() {
Text('☀️')
.fontSize(14)
Slider({
value: this.currentBrightness * 100,
min: 0,
max: 100,
step: 5,
style: SliderStyle.OutSet
})
.layoutWeight(1)
.onChange(async (value: number) => {
this.currentBrightness = value / 100;
if (!this.isFollowSystem) {
await this.brightnessManager.setWindowBrightness(this.currentBrightness);
}
})
Text('🔆')
.fontSize(20)
}
.width('100%')
Text(`亮度: ${Math.round(this.currentBrightness * 100)}%`)
.fontSize(14)
.fontColor('#666')
.margin({ top: 8 })
}
.width('100%')
.padding(16)
.backgroundColor('#f5f5f5')
.borderRadius(12)
// 快捷亮度预设
Row() {
this.QuickButton('夜间', 0.15)
this.QuickButton('柔和', 0.35)
this.QuickButton('标准', 0.55)
this.QuickButton('明亮', 0.8)
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ top: 20 })
}
.width('100%')
.height('100%')
.padding(20)
}
@Builder
QuickButton(label: string, brightness: number) {
Button(label)
.fontSize(14)
.backgroundColor(this.currentBrightness === brightness ? '#4CAF50' : '#e0e0e0')
.fontColor(this.currentBrightness === brightness ? '#fff' : '#333')
.borderRadius(20)
.width(70)
.height(36)
.onClick(async () => {
this.currentBrightness = brightness;
this.isFollowSystem = false;
await this.brightnessManager.setWindowBrightness(brightness);
})
}
}
export { BrightnessManager };
3.2 屏幕方向锁定与超时设置:视频播放器场景
视频播放器有两个刚需:播放时横屏、播放时常亮。这两个需求通过 setPreferredOrientation 和 setWindowKeepScreenOn 实现。
import { window } from '@kit.ArkUI';
/**
* 屏幕方向与超时管理器
*/
class DisplayControlManager {
private mainWindow: window.Window | null = null;
/**
* 初始化
*/
async init(context: Context): Promise<void> {
this.mainWindow = await window.getLastWindow(context);
}
/**
* 设置屏幕方向
* @param orientation 方向枚举
*/
async setOrientation(orientation: window.Orientation): Promise<void> {
if (!this.mainWindow) return;
try {
await this.mainWindow.setPreferredOrientation(orientation);
const nameMap: Record<number, string> = {
0: '未指定',
1: '竖屏',
2: '横屏(左旋)',
3: '横屏(右旋)',
4: '反向竖屏',
5: '传感器自动旋转',
6: '传感器竖屏',
7: '传感器横屏',
};
console.info(`[Display] 屏幕方向: ${nameMap[orientation] || orientation}`);
} catch (err) {
console.error(`[Display] 设置方向失败: ${JSON.stringify(err)}`);
}
}
/**
* 锁定竖屏
*/
async lockPortrait(): Promise<void> {
await this.setOrientation(window.Orientation.PORTRAIT);
}
/**
* 锁定横屏
*/
async lockLandscape(): Promise<void> {
await this.setOrientation(window.Orientation.LANDSCAPE);
}
/**
* 自动旋转(跟随传感器)
*/
async autoRotate(): Promise<void> {
await this.setOrientation(window.Orientation.AUTO_ROTATION);
}
/**
* 设置屏幕保持常亮
* @param keepOn true=常亮,false=跟随系统超时
*/
async setKeepScreenOn(keepOn: boolean): Promise<void> {
if (!this.mainWindow) return;
try {
await this.mainWindow.setWindowKeepScreenOn(keepOn);
console.info(`[Display] 屏幕常亮: ${keepOn ? '开启' : '关闭'}`);
} catch (err) {
console.error(`[Display] 设置常亮失败: ${JSON.stringify(err)}`);
}
}
/**
* 获取当前屏幕方向
*/
async getCurrentOrientation(): Promise<window.Orientation> {
if (!this.mainWindow) return window.Orientation.UNSPECIFIED;
try {
const properties = await this.mainWindow.getWindowProperties();
return properties.orientation;
} catch (err) {
return window.Orientation.UNSPECIFIED;
}
}
}
/**
* 视频播放器页面
* 播放时自动横屏 + 常亮
*/
@Entry
@Component
struct VideoPlayerPage {
@State isPlaying: boolean = false;
@State isFullscreen: boolean = false;
private displayControl: DisplayControlManager = new DisplayControlManager();
async aboutToAppear(): Promise<void> {
const context = getContext(this);
await this.displayControl.init(context);
}
/**
* 进入全屏播放
*/
async enterFullscreen(): Promise<void> {
this.isFullscreen = true;
// 横屏 + 常亮
await this.displayControl.lockLandscape();
await this.displayControl.setKeepScreenOn(true);
// 隐藏状态栏(沉浸式)
const mainWindow = await window.getLastWindow(getContext(this));
await mainWindow.setWindowLayoutFullScreen(true);
}
/**
* 退出全屏播放
*/
async exitFullscreen(): Promise<void> {
this.isFullscreen = false;
// 恢复竖屏 + 取消常亮
await this.displayControl.lockPortrait();
await this.displayControl.setKeepScreenOn(false);
// 恢复状态栏
const mainWindow = await window.getLastWindow(getContext(this));
await mainWindow.setWindowLayoutFullScreen(false);
}
build() {
Column() {
// 视频区域
Stack() {
// 视频占位
Column() {
Text('🎬')
.fontSize(48)
Text(this.isPlaying ? '播放中...' : '已暂停')
.fontSize(14)
.fontColor('#fff')
.margin({ top: 8 })
}
.width('100%')
.height(this.isFullscreen ? '100%' : 220)
.backgroundColor('#000')
.justifyContent(FlexAlign.Center)
.onClick(async () => {
this.isPlaying = !this.isPlaying;
if (this.isPlaying) {
await this.displayControl.setKeepScreenOn(true);
}
})
// 全屏按钮
if (!this.isFullscreen) {
Button(this.isFullscreen ? '退出全屏' : '全屏')
.fontSize(12)
.backgroundColor('#80000000')
.position({ x: '80%', y: 10 })
.onClick(() => this.enterFullscreen())
}
// 退出全屏按钮
if (this.isFullscreen) {
Button('退出')
.fontSize(12)
.backgroundColor('#80000000')
.position({ x: 10, y: 10 })
.onClick(() => this.exitFullscreen())
}
}
.width('100%')
.height(this.isFullscreen ? '100%' : 220)
// 非全屏时显示控制面板
if (!this.isFullscreen) {
Column() {
Text('播放控制')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
Row() {
Button('播放/暂停')
.onClick(() => {
this.isPlaying = !this.isPlaying;
})
Button('全屏播放')
.onClick(() => this.enterFullscreen())
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.width('100%')
.padding(20)
}
}
.width('100%')
.height('100%')
}
/**
* 页面销毁时恢复设置
*/
async aboutToDisappear(): Promise<void> {
if (this.isFullscreen) {
await this.exitFullscreen();
}
}
}
export { DisplayControlManager };
3.3 折叠屏适配:展开/折叠的布局响应
折叠屏是 HarmonyOS 生态的明星特性。应用需要根据折叠状态切换布局——折叠时是手机布局,展开时是平板布局。
import { display } from '@kit.ArkUI';
/**
* 折叠屏适配管理器
* 监听折叠状态变化,提供布局建议
*/
class FoldableManager {
private foldStatus: display.FoldStatus = display.FoldStatus.FOLD_STATUS_UNKNOWN;
private listeners: ((status: display.FoldStatus) => void)[] = [];
/**
* 折叠状态枚举说明:
* FOLD_STATUS_UNKNOWN = 0 未知
* FOLD_STATUS_EXPANDED = 1 展开(平板模式)
* FOLD_STATUS_FOLDED = 2 折叠(手机模式)
* FOLD_STATUS_HALF_FOLDED = 3 半折叠(帐篷/笔记本模式)
*/
/**
* 初始化折叠屏监听
*/
init(): void {
// 获取当前折叠状态
try {
this.foldStatus = display.getFoldStatusSync();
console.info(`[Foldable] 初始状态: ${this.foldStatus}`);
} catch (err) {
console.warn(`[Foldable] 获取折叠状态失败: ${JSON.stringify(err)}`);
}
// 监听折叠状态变化
display.on('foldStatusChange', (status: display.FoldStatus) => {
console.info(`[Foldable] 折叠状态变更: ${this.foldStatus} → ${status}`);
this.foldStatus = status;
this.notifyListeners(status);
});
}
/**
* 是否展开状态
*/
isExpanded(): boolean {
return this.foldStatus === display.FoldStatus.FOLD_STATUS_EXPANDED;
}
/**
* 是否折叠状态
*/
isFolded(): boolean {
return this.foldStatus === display.FoldStatus.FOLD_STATUS_FOLDED;
}
/**
* 是否半折叠状态
*/
isHalfFolded(): boolean {
return this.foldStatus === display.FoldStatus.FOLD_STATUS_HALF_FOLDED;
}
/**
* 获取当前布局模式建议
*/
getLayoutMode(): 'phone' | 'tablet' | 'tent' {
switch (this.foldStatus) {
case display.FoldStatus.FOLD_STATUS_EXPANDED:
return 'tablet';
case display.FoldStatus.FOLD_STATUS_HALF_FOLDED:
return 'tent';
case display.FoldStatus.FOLD_STATUS_FOLDED:
default:
return 'phone';
}
}
/**
* 注册状态变更监听
*/
onFoldStatusChange(callback: (status: display.FoldStatus) => void): void {
this.listeners.push(callback);
}
/**
* 通知监听器
*/
private notifyListeners(status: display.FoldStatus): void {
this.listeners.forEach(cb => cb(status));
}
/**
* 销毁监听
*/
destroy(): void {
display.off('foldStatusChange');
this.listeners = [];
}
}
/**
* 折叠屏自适应页面
* 根据折叠状态切换手机/平板布局
*/
@Entry
@Component
struct FoldableAdaptivePage {
@State layoutMode: 'phone' | 'tablet' | 'tent' = 'phone';
@State screenWidth: number = 360;
@State screenHeight: number = 800;
private foldableManager: FoldableManager = new FoldableManager();
aboutToAppear(): void {
this.foldableManager.init();
this.layoutMode = this.foldableManager.getLayoutMode();
// 监听折叠状态变化
this.foldableManager.onFoldStatusChange((status) => {
this.layoutMode = this.foldableManager.getLayoutMode();
});
// 监听屏幕尺寸变化
display.on('displaySizeChange', display.getDefaultDisplaySync().id, (data) => {
this.screenWidth = px2vp(data.width);
this.screenHeight = px2vp(data.height);
console.info(`[Foldable] 屏幕尺寸: ${this.screenWidth}x${this.screenHeight}`);
});
// 获取初始屏幕尺寸
const displayInfo = display.getDefaultDisplaySync();
this.screenWidth = px2vp(displayInfo.width);
this.screenHeight = px2vp(displayInfo.height);
}
aboutToDisappear(): void {
this.foldableManager.destroy();
display.off('displaySizeChange');
}
build() {
if (this.layoutMode === 'tablet') {
// 平板布局:双栏
this.TabletLayout()
} else if (this.layoutMode === 'tent') {
// 帐篷模式:上下分区
this.TentLayout()
} else {
// 手机布局:单栏
this.PhoneLayout()
}
}
/**
* 手机布局:单栏列表
*/
@Builder
PhoneLayout() {
Column() {
Text('📱 手机模式')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
// 列表内容
List() {
ForEach(['推荐内容', '热门话题', '最新发布', '关注动态', '附近的人'], (item: string) => {
ListItem() {
Row() {
Text('📄')
.fontSize(24)
.margin({ right: 12 })
Text(item)
.fontSize(16)
.layoutWeight(1)
}
.width('100%')
.padding(16)
.backgroundColor('#f5f5f5')
.borderRadius(12)
.margin({ bottom: 8 })
}
})
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.padding(16)
}
/**
* 平板布局:双栏
*/
@Builder
TabletLayout() {
Row() {
// 左侧:导航列表
Column() {
Text('📋 导航')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
ForEach(['推荐内容', '热门话题', '最新发布', '关注动态', '附近的人'], (item: string) => {
Text(item)
.fontSize(16)
.padding(12)
.borderRadius(8)
.width('100%')
.margin({ bottom: 4 })
.backgroundColor('#f0f0f0')
})
}
.width('35%')
.height('100%')
.padding(16)
.backgroundColor('#fafafa')
// 右侧:内容详情
Column() {
Text('📖 内容详情')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
Column() {
Text('展开模式下的详细内容区域')
.fontSize(16)
.lineHeight(28)
Text('可以展示更丰富的信息,充分利用大屏空间')
.fontSize(14)
.fontColor('#666')
.margin({ top: 12 })
}
.padding(20)
.backgroundColor('#fff')
.borderRadius(12)
.layoutWeight(1)
}
.layoutWeight(1)
.height('100%')
.padding(16)
}
.width('100%')
.height('100%')
}
/**
* 帐篷模式:上下分区
*/
@Builder
TentLayout() {
Column() {
// 上半屏:展示区
Column() {
Text('🏕️ 帐篷模式 - 展示区')
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text('适合放在桌面上查看')
.fontSize(14)
.fontColor('#666')
.margin({ top: 8 })
}
.width('100%')
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.backgroundColor('#E3F2FD')
// 下半屏:控制区
Column() {
Text('控制面板')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 12 })
Row() {
Button('◀ 上一项')
Button('▶ 下一项')
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.width('100%')
.height(180)
.padding(16)
.backgroundColor('#fafafa')
}
.width('100%')
.height('100%')
}
}
export { FoldableManager };
四、踩坑与注意事项
4.1 窗口亮度 vs 系统亮度
坑:应用内修改亮度后,退出应用发现系统亮度也被改了。
解:使用 setWindowBrightness() 只影响当前窗口,退出后自动恢复。千万不要用系统 API 修改全局亮度——那需要系统级权限,而且会影响用户的其他应用。
4.2 setPreferredOrientation 的时机
坑:在 aboutToAppear 中设置方向,但页面已经渲染了竖屏布局,切换后布局错乱。
解:在 onWindowStageCreate 阶段就设置方向,或者在设置方向后延迟 100ms 再加载内容。
// ✅ 正确:提前设置方向
onWindowStageCreate() {
window.getLastWindow(context).then(win => {
win.setPreferredOrientation(window.Orientation.LANDSCAPE);
});
}
4.3 setWindowKeepScreenOn 的电量消耗
坑:忘记关闭常亮,导致电量快速消耗。
解:在页面 aboutToDisappear 中务必关闭常亮。对于视频播放器,暂停时也应考虑关闭。
4.4 折叠屏的 displaySizeChange 频繁触发
坑:折叠/展开过程中,displaySizeChange 会连续触发多次,导致布局频繁重绘。
解:加入防抖,只在尺寸稳定后执行布局切换。
private resizeTimer: number = -1;
display.on('displaySizeChange', displayId, (data) => {
if (this.resizeTimer !== -1) {
clearTimeout(this.resizeTimer);
}
this.resizeTimer = setTimeout(() => {
this.handleResize(data.width, data.height);
}, 300);
});
4.5 半折叠模式的特殊处理
坑:半折叠(帐篷模式)时,屏幕被物理分为上下两半,但系统仍然认为是一个完整屏幕。
解:在半折叠模式下,主动将布局分为上下两个区域,上半部分展示内容,下半部分提供控制。
五、HarmonyOS 6 适配
5.1 API 变化一览
| 变化项 | HarmonyOS 5 | HarmonyOS 6 |
|---|---|---|
| 折叠状态 | 3 种(展开/折叠/半折叠) | 新增 FOLD_STATUS_FULL_EXPANDED(完全展开) |
| 刷新率 | 无法主动设置 | 新增 setDisplayRefreshRate() |
| HDR | 不支持 | 新增 HDR 显示模式支持 |
| 多屏协同 | 基础支持 | 新增跨屏拖拽、无缝切换 |
| 屏幕圆角 | 不感知 | 新增 display.getCutoutInfo() 获取刘海/挖孔信息 |
5.2 迁移指南
// HarmonyOS 5:无法设置刷新率
// 只能读取 display.getDefaultDisplaySync().refreshRate
// HarmonyOS 6:可以主动设置刷新率
import { display } from '@kit.ArkUI';
display.setDisplayRefreshRate(displayId, 120); // 设置 120Hz
5.3 注意事项
- 刷新率设置:高刷新率会增加功耗,建议仅在游戏等场景开启,普通场景使用 60Hz。
- HDR 模式:需要屏幕硬件支持,使用前应检查
isHdrSupported()。 - 刘海/挖孔适配:HarmonyOS 6 新增的
getCutoutInfo()可以获取屏幕异形区域,避免内容被遮挡。
六、总结
mindmap
root((显示设置))
屏幕亮度
窗口亮度覆盖
跟随系统亮度
阅读器护眼模式
屏幕方向
竖屏/横屏锁定
传感器自动旋转
视频播放器场景
屏幕超时
保持常亮
播放/导航场景
记得关闭常亮
分辨率与刷新率
高刷新率设置(HarmoneyOS 6)
HDR 模式
功耗与体验平衡
折叠屏适配
折叠状态监听
手机/平板布局切换
半折叠帐篷模式
防抖处理
注意事项
窗口亮度 vs 系统亮度
方向设置时机
常亮电量消耗
尺寸变化防抖
| 知识点 | 要点 |
|---|---|
| 亮度控制 | 使用窗口亮度覆盖,不修改系统全局亮度 |
| 方向控制 | setPreferredOrientation 设置方向,视频场景横屏+常亮 |
| 保持常亮 | setWindowKeepScreenOn(true),退出时务必关闭 |
| 折叠屏 | 监听 foldStatusChange,根据状态切换布局模式 |
| 防抖 | 折叠/尺寸变化时加入防抖,避免频繁重绘 |
| HarmonyOS 6 | 新增刷新率设置、HDR 模式、刘海/挖孔信息 |
显示设置就像给应用穿衣服——不同场合穿不同的衣服。阅读时穿"护眼模式",看视频时穿"横屏常亮",折叠屏展开时换上"平板正装"。掌握了这些,你的应用就能在任何屏幕上都体面登场。
- 点赞
- 收藏
- 关注作者
评论(0)