










速查手册定位
本文档是快速修正单位转换API弃用警告的实用指南,提供直接可复制的代码示例,适合开发过程中快速查阅和修改。
弃用 全局方法 px2vp()、vp2px() 等无法在多窗口、多UI实例场景下准确定位屏幕密度,因此被标记为弃用。
推荐 使用 UIContext 实例调用转换方法,基于当前UI实例的正确屏幕参数进行转换,确保结果准确。
// ✅ 推荐修正方式(两步操作)
import { UIContext } from '@kit.ArkUI'; // 1. 导入UIContext
@Entry
@Component
struct MyComponent {
// 2. 提前获取UIContext实例(成员变量缓存,性能最优)
private uiContext: UIContext = this.getUIContext();
build() {
Column() {
Text("示例文本")
// 3. 替换全局方法为UIContext调用
.width(this.uiContext.px2vp(220))
.height(this.uiContext.px2vp(40))
.backgroundColor(0xF9CF93)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.fontSize(this.uiContext.fp2px(12)) // fp单位转换同理
}
.margin(5)
}
}
如果需要快速修改现有代码而不改变原有结构,可直接在属性中调用:
// ⚡️ 快速修正方式(适合存量代码快速修改)
Text("示例文本")
.width(px2vp(220))
.width(this.getUIContext().px2vp(220))
.height(40)
注意:这种方式会在每次组件重组时都调用getUIContext(),性能略低于成员变量缓存方式,适合临时快速修改。
// ❌ 旧写法(弃用)
@Component
struct OldDemo {
build() {
Row() {
Image('test.png')
.width(px2vp(100))
.height(px2vp(100))
Text('标题')
.fontSize(fp2px(18))
.margin({ left: px2vp(16) })
}
.padding(px2vp(12))
}
}
// ✅ 新写法(推荐)
import { UIContext } from '@kit.ArkUI';
@Component
struct NewDemo {
private uiContext: UIContext = this.getUIContext();
build() {
Row() {
Image('test.png')
.width(this.uiContext.px2vp(100))
.height(this.uiContext.px2vp(100))
Text('标题')
.fontSize(this.uiContext.fp2px(18))
.margin({ left: this.uiContext.px2vp(16) })
}
.padding(this.uiContext.px2vp(12))
}
}
// ❌ 旧写法
@Entry
@Component
struct ListDemo {
build() {
List() {
ForEach([1, 2, 3, 4, 5], (item: number) => {
ListItem() {
Column() {
Text(`列表项 ${item}`)
.height(px2vp(50))
.padding({ left: px2vp(20) })
}
.width('100%')
}
})
}
.width('100%')
}
}
// ✅ 新写法
import { UIContext } from '@kit.ArkUI';
@Entry
@Component
struct ListDemo {
private uiContext: UIContext = this.getUIContext();
// 提前计算常量值,避免列表滚动时重复计算
private itemHeight: number = this.uiContext.px2vp(50);
private paddingLeft: number = this.uiContext.px2vp(20);
build() {
List() {
ForEach([1, 2, 3, 4, 5], (item: number) => {
ListItem() {
Column() {
Text(`列表项 ${item}`)
.height(this.itemHeight)
.padding({ left: this.paddingLeft })
}
.width('100%')
}
})
}
.width('100%')
}
}
// ❌ 旧写法
@Component
struct ConditionDemo {
@State isLarge: boolean = false;
build() {
Column() {
if (this.isLarge) {
Text('大尺寸文本')
.fontSize(fp2px(24))
.width(px2vp(300))
} else {
Text('小尺寸文本')
.fontSize(fp2px(14))
.width(px2vp(150))
}
Button('切换尺寸')
.onClick(() => {
this.isLarge = !this.isLarge;
})
}
}
}
// ✅ 新写法
import { UIContext } from '@kit.ArkUI';
@Component
struct ConditionDemo {
@State isLarge: boolean = false;
private uiContext: UIContext = this.getUIContext();
// 预计算所有需要的尺寸
private largeFontSize: number = this.uiContext.fp2px(24);
private largeWidth: number = this.uiContext.px2vp(300);
private smallFontSize: number = this.uiContext.fp2px(14);
private smallWidth: number = this.uiContext.px2vp(150);
build() {
Column() {
if (this.isLarge) {
Text('大尺寸文本')
.fontSize(this.largeFontSize)
.width(this.largeWidth)
} else {
Text('小尺寸文本')
.fontSize(this.smallFontSize)
.width(this.smallWidth)
}
Button('切换尺寸')
.onClick(() => {
this.isLarge = !this.isLarge;
})
}
}
}
// ❌ 旧写法
@Component
struct DynamicDemo {
@State scale: number = 1.0;
build() {
Column() {
Text('动态尺寸文本')
.fontSize(fp2px(16) * this.scale)
Slider({ min: 0.5, max: 2.0, value: 1.0 })
.width(px2vp(200))
.onChange((value: number) => {
this.scale = value;
})
}
}
}
// ✅ 新写法
import { UIContext } from '@kit.ArkUI';
@Component
struct DynamicDemo {
@State scale: number = 1.0;
private uiContext: UIContext = this.getUIContext();
// 基础尺寸只计算一次
private baseFontSize: number = this.uiContext.fp2px(16);
private sliderWidth: number = this.uiContext.px2vp(200);
build() {
Column() {
Text('动态尺寸文本')
.fontSize(this.baseFontSize * this.scale) // 动态计算时使用预计算的基础值
Slider({ min: 0.5, max: 2.0, value: 1.0 })
.width(this.sliderWidth)
.onChange((value: number) => {
this.scale = value;
})
}
}
}
|
弃用的全局方法 |
新的UIContext方法 |
功能说明 |
|
px2vp(pxValue) |
uiContext.px2vp(pxValue) |
像素px转虚拟像素vp |
|
vp2px(vpValue) |
uiContext.vp2px(vpValue) |
虚拟像素vp转像素px |
|
fp2px(fpValue) |
uiContext.fp2px(fpValue) |
字体像素fp转像素px |
|
px2fp(pxValue) |
uiContext.px2fp(pxValue) |
像素px转字体像素fp |
|
lpx2px(lpxValue) |
uiContext.lpx2px(lpxValue) |
逻辑像素lpx转像素px |
|
px2lpx(pxValue) |
uiContext.px2lpx(pxValue) |
像素px转逻辑像素lpx |
常见误区
❌ 不要在aboutToAppear()中调用getUIContext()进行布局计算,此时UI实例可能尚未准备好
❌ 不要在循环或build()中重复调用getUIContext(),会影响性能
❌ 不要缓存UIContext到全局变量,可能导致上下文失效
✅ 推荐在成员变量中初始化UIContext实例,组件内共享使用
在build()方法中直接调用this.getUIContext().px2vp()是安全的,不会导致运行时错误,但从性能角度考虑,建议将转换结果缓存到成员变量中,避免每次重组都重复计算。
• 性能提升:避免每次组件重组都重复获取UIContext和执行转换计算
• 结果稳定:同一组件生命周期内屏幕参数不会变化,转换结果固定
• 代码清晰:所有尺寸定义集中在组件顶部,便于维护和修改
在多窗口应用中,每个窗口的UIContext是独立的,确保每个窗口内的组件使用自己的UIContext实例进行转换,不要跨窗口共享UIContext。
在DevEco Studio中可以使用正则表达式批量替换:
// 查找:
px2vp\((.*?)\)
vp2px\((.*?)\)
fp2px\((.*?)\)
// 替换为:
this.getUIContext().px2vp($1)
this.getUIContext().vp2px($1)
this.getUIContext().fp2px($1)
注意:批量替换后需要检查代码逻辑,确保this指向正确,非组件内的调用需要单独处理。
1. ✅ 所有全局单位转换方法已替换为UIContext方式
2. ✅ 导入了UIContext:import { UIContext } from '@kit.ArkUI';
3. ✅ 优先使用成员变量缓存UIContext实例
4. ✅ 常量转换值提前计算,避免重复计算
5. ✅ 不在aboutToAppear()中进行单位转换
6. ✅ 多窗口场景下每个窗口使用独立的UIContext
7. ✅ 没有将UIContext缓存到全局变量
8. ✅ 编译后无弃用警告提示
IDE提示
DevEco Studio会对已弃用的全局方法显示黄色波浪线警告,将鼠标悬停在警告上会自动提示修复建议,可通过快速修复功能一键替换为UIContext方式。
按照上述方法修正后,弃用警告将完全消失,代码符合HarmonyOS最新开发规范
文档版本:V1.0 | 适配版本:HarmonyOS NEXT API 12+ | 更新日期:2024年4月
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。