as

Settings
Sign out
Notifications
Alexa
亚马逊应用商店
Ring
AWS
文档
Support
Contact Us
My Cases
新手入门
设计和开发
应用发布
参考
支持

密度无关像素

密度无关像素

Vega渲染器上的React Native 0.83默认以密度无关像素 (dp) 为单位。本页阐述了单位更改内容,以及如何更新应用中的布局值、输入处理、自定义原生界面和图像。本页为代码迁移步骤4.9的扩展内容。

RN 0.83中的布局值、组件尺寸、转换、滚动偏移量和指针坐标,均以逻辑dp为单位。Vega会在渲染边界处将这些逻辑值一次性换算为物理像素。如果根据RN 0.72的物理输出调整应用,请在发布前审核每个数值型布局值。

关于密度无关像素

dp是一种逻辑用户界面单位。Vega使用显示屏比例系数,将其映射为物理像素:

物理像素 = dp × 比例系数
dp = 物理像素 ÷ 比例系数

在React Native 0.83之前,禁用dp渲染的应用会将width: 100绘制为100物理像素。自React Native 0.83起,同一数值即表示100dp。比例系数为2或2.66时,Vega分别绘制200物理像素和266物理像素。这是需要评估的主要布局影响。

Vega画布的参考尺寸为960×540dp,在1080p显示屏上的比例系数为2。

涉及单位更改的内容

RN 0.83会将dp映射应用于整个用户界面路径:

  • Vega会缩放最终绘制画布及损坏区域。
  • 窗口大小和位置在图形边界处以物理像素为单位,但在应用代码中仍以dp为单位。
  • 指针、触摸、大小调整、窗口位置和遮蔽事件在返回React Native时均以dp为单位。
  • 子窗口、弹出窗口、模态、纹理缓存层和虚拟表面均使用相同比例。
  • DimensionsuseWindowDimensions()会报告逻辑尺寸。PixelRatio.get()会报告物理像素与dp的比率。

未涉及单位更改的内容

以下两项保留原有行为:

  • 位图数据。dp渲染不会缩放位图数据,也不会更改图像元数据。图像解码器、位图、像素图和纹理仍使用物理像素尺寸。
  • 字体缩放。dp渲染不会替代无障碍字体缩放。继续使用React Native文本API和fontScale,以适配用户选择的文本大小。

PixelRatio和DeviceInfo TurboModule

PixelRatio是一种React Native JavaScript实用工具,而非独立的TurboModule。PixelRatio.get()会读取Dimensions.get('window').scale。原生DeviceInfo TurboModule会向Dimensions提供widthheightscalefontScale

在RN 0.83中,DeviceInfo会报告逻辑窗口尺寸以及当前的物理像素与dp之间的比例。还会通过didUpdateDimensions发布每个表面的尺寸更新数据。

Vega使用密度无关像素的原因

Android和iOS上的React Native均默认使用逻辑单位。Vega会对所有RN 0.83应用采用相同的默认坐标模型,因此三个目标上的几何行为是一致的。

现在采用的统一单位合约涵盖了标准React Native组件、自定义原生组件、TurboModules、第三方库、窗口API、渲染及输入事件。应用会以逻辑单位描述用户界面几何,而Vega会在图形边界处进行换算。用户界面比例在不同画布分辨率的设备上保持一致,而可缩放用户界面可以选择分辨率更高的画布,无需单独进行像素布局。

应用中的更改

下表将RN 0.72的常见模式映射到RN 0.83的对应行为。

应用中的模式 RN 0.83行为 解决方法
数值型长度样式和Yoga常量,例如width: 100、边距、内边距、边框和偏移量 值为100时,渲染为100 × scaleFactor物理像素 使用logicalValue = legacyPixelValue ÷ baselineScaleFactor换算像素调优后的值
Flexbox和百分比尺寸 数值始终与逻辑视口保持相对关系 无需进行单位转换。验证生成的布局。
经过硬编码的1920 × 1080屏幕几何 布局与当前逻辑视口不匹配 使用useWindowDimensions()、Flexbox或百分比
指针或滚动坐标除以PixelRatio.get() 事件已以dp为单位返回 移除手动换算
调用Vega用户界面API的自定义原生组件 Vega用户界面API以dp为单位处理几何值 直接传递React Native值,无需转换
每种密度对应一项光栅资产 合成器会放大低分辨率源图 添加密度变体,或请求更高分辨率的远程图像

转换像素调优后的值

RN 0.83中的数值型长度值均以dp为单位。使用迁移前基线的比例系数,对“调优”值进行物理像素转换:

逻辑值 = 原有物理像素值 ÷ 基线比例系数

对于之前调优的应用(比例系数为2):

// ❌ 之前 (RN 0.72) — 以物理像素为单位调优的值
const legacyStyles = StyleSheet.create({
  card: {
    width: 320,
    height: 180,
    borderRadius: 12,
  },
});

//✅ 之后 (RN 0.83) — 物理尺寸相同,以dp为单位
const styles = StyleSheet.create({
  card: {
    width: 160,
    height: 90,
    borderRadius: 6,
  },
});

对以物理像素为单位进行校准的边距、内边距、边框、转换、阴影、动画距离、SVG尺寸及自定义画布坐标进行相同转换。密度无关UX规范中原有的值保持不变。

替换固定屏幕尺寸

经过硬编码的屏幕常量不再匹配逻辑视口。改为在运行时读取尺寸。

// ❌ 之前 (RN 0.72)
const screenWidth = 1920;
const panelWidth = screenWidth / 3;

// ✅ 之后 (RN 0.83)
function Panel() {
  const {width} = useWindowDimensions();
  return <View style={{width: width / 3, height: '100%'}} />;
}

useWindowDimensions()会返回逻辑尺寸。分配React Native样式前,请勿将其转换为物理像素。

使用逻辑输入坐标

RN 0.83以dp为单位,报告指针和触摸坐标:

const {pageX: x, pageY: y} = event.nativeEvent;

将这些值直接传递到您的布局、手势、焦点、命中测试、滚动和动画代码。如果应用对以dp为单位的坐标进行了转换,则移除此操作,否则会导致该值被缩放两次。

以dp为单位保留自定义原生接口

在React Native边界处,以dp为单位定义自定义组件和TurboModule几何值。

NativeCardModule.setBounds({x, y, width, height}); // 所有值均以dp为单位。

当原生实现调用Vega窗口、视图、图层或画布API时,原样转发这些值。只有在调用明确要求以物理像素为单位的API(如位图解码器或更底层的图形API)时,才会根据当前比例系数进行转换。当同一模块中出现两种单位时,应在名称中加入单位,例如widthDptargetWidthPx

处理图像

图像布局和图像数据使用不同的单位:

  • <图像样式=>以dp为单位。
  • 源位图尺寸、解码后的图像尺寸、行字节和纹理尺寸则以物理像素为单位。
  • React Native提供首选逻辑解码尺寸时,Vega图像管道会在解码前将该尺寸乘以当前比例系数。请勿在您自己的代码中对<图像>样式或首选布局尺寸进行乘法运算。
  • 源图需要足以匹配其渲染dp尺寸的物理像素。以比例系数2、尺寸320x180 dp进行图像渲染时,源图像素至少要达到640×360,才能避免放大。

本地资产

在同一目录中提供多种密度变体。Metro和React Native会根据当前密度选择匹配的资产。

assets/
  icon.png
  icon@2x.png
  icon@3x.png
<Image source={require('./assets/icon.png')} style={{width: 48, height: 48}} />

对于2.66这类非整数密度,需提供@3x数据。React Native会选择分辨率更高的资产,避免放大低分辨率的源图。对于图标等非摄影类图形,建议优先使用SVG。

迁移核对清单

要完成dp迁移,请完成以下步骤:

  1. 将应用升级到RN 0.83,并移除所有与新默认行为重复的RN 0.72 dp实验标记。
  2. 清查应用中的数值型长度值、固定画布常量(如19201080)以及所有坐标转换辅助工具。
  3. 使用logicalValue = legacyPixelValue ÷ baselineScaleFactor转换以物理像素为单位调优的值,密度无关UX规范中原有的值则保持不变。
  4. RN 0.83报告的指针、手势、滚动、大小调整和窗口坐标均以dp为单位。
  5. 更改React Native与原生层之间的自定义几何值契约,使其以dp为单位,且仅在明确要求以物理像素为单位的API处,保留像素转换。
  6. 以Flexbox、百分比、DimensionsuseWindowDimensions()替换经过硬编码的屏幕尺寸。
  7. 添加本地位图密度变体,并确认每张图片的物理像素足以匹配其渲染逻辑尺寸。
  8. 测试每种支持密度下的主窗口、模态、弹出窗口、警报、子窗口、滚动、手势、焦点、无障碍功能、本地化以及从右到左的布局。

外部资源


Last updated: 2026年8月19日