Dimensions 是 React Native 提供的一个 核心 API 模块,用于获取设备的屏幕宽高、窗口尺寸或特定元素的尺寸。它的作用类似于 iOS 原生中的 UIScreen.main.bounds 或 UIWindow 的尺寸信息。
基本用法
import { Dimensions } from 'react-native';
// 获取整个屏幕的尺寸(包括状态栏、导航栏占用的区域)
const screen = Dimensions.get('window');
console.log(screen.width, screen.height); // 例如:375, 812
// 获取应用窗口的尺寸(在某些设备上可能与 screen 相同,但在分屏或折叠屏下会不同)
const window = Dimensions.get('window'); // 常用这个
// 解构赋值,并重命名变量
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
注意:在 React Native 中,
Dimensions.get('window')返回的是应用可用的窗口尺寸(即除去系统状态栏、底部安全区等之外的区域,但具体行为取决于平台和 RN 版本)。大多数情况下直接用'window'即可,它与UIScreen.main.bounds最接近。
与 iOS 原生的对比
| 场景 | React Native | iOS 原生 |
|---|---|---|
| 获取屏幕尺寸 | Dimensions.get('window') |
UIScreen.main.bounds |
| 监听尺寸变化(旋转/多窗口) | Dimensions.addEventListener('change', handler) |
viewWillTransition(to:with:) 或 UIContentSizeCategory 通知 |
| 获取逻辑像素(points) | 直接返回的数字就是逻辑像素(dp/points) | 原生中的 bounds.size 也是 points |
| 物理像素 | 需要用 PixelRatio.getPixelSizeForLayoutSize(size)
|
UIScreen.main.scale |
监听屏幕尺寸变化
当设备旋转、iPad 分屏或折叠屏折叠时,Dimensions 的值会变化。你需要监听变化并更新 UI。
import React, { useState, useEffect } from 'react';
import { Dimensions, View, Text } from 'react-native';
const ResponsiveComponent = () => {
const [screenWidth, setScreenWidth] = useState(Dimensions.get('window').width);
useEffect(() => {
// 添加监听器
const subscription = Dimensions.addEventListener('change', ({ window, screen }) => {
setScreenWidth(window.width);
// 可以在这里强制重新计算样式或重新渲染
});
// 清理监听器
return () => subscription?.remove();
}, []);
return (
<View style={{ width: screenWidth, backgroundColor: 'lightblue' }}>
<Text>当前屏幕宽度: {screenWidth}</Text>
</View>
);
};
注意:在较新版本的 RN 中(0.65+),推荐使用
addEventListener返回的订阅对象调用remove()。旧版本中可能使用Dimensions.removeEventListener,但已废弃。
常见使用场景
- 响应式布局:根据屏幕宽度动态计算卡片宽度或字体大小。
- 全屏组件:例如 Modal、全屏图片预览,需要占满整个窗口。
- 自定义横竖屏适配:监听尺寸变化后重新布局(但 RN 的 Flexbox 通常会自动适配,不需要手动处理)。
-
计算元素位置:配合
onLayout事件,获取某个组件相对于屏幕的绝对位置。
重要注意事项
1. 初始值的获取时机
在组件首次渲染时,Dimensions.get('window') 会返回正确的值。但如果组件在屏幕旋转后才挂载,获取到的也是最新的正确值。不过,如果你的组件需要在尺寸变化后立即计算某些布局(如动画起始位置),建议在 useEffect 中读取最新值并设置状态。
2. 与 useWindowDimensions 的对比
React Native 还提供了一个 Hook:useWindowDimensions,它会在屏幕尺寸变化时自动触发组件重新渲染,无需手动监听。
import { useWindowDimensions } from 'react-native';
const { width, height } = useWindowDimensions();
// 直接使用,尺寸变化时组件自动更新
推荐优先使用 useWindowDimensions,它更简洁且不易出错。
3. 折叠屏/多窗口支持
在 iPad 多任务分屏、Android 折叠屏或 Chrome OS 中,Dimensions.get('window') 会返回当前应用窗口的实际大小。你需要监听变化并重新布局,否则部分内容可能被裁剪或留白。
4. 单位是“点”(points)
返回的数字是逻辑像素,与 iOS 的 UIScreen.main.bounds.width 含义完全一致。如果需要物理像素(例如绘制 1 物理像素的细线),可以使用 PixelRatio.getPixelSizeForLayoutSize(1)。
总结
| API | 作用 | 推荐度 |
|---|---|---|
Dimensions.get('window') |
同步获取当前窗口尺寸 | 可用于类组件或非 React 上下文 |
useWindowDimensions() |
Hook,自动响应尺寸变化 | 优先使用 |
Dimensions.addEventListener |
手动监听变化 | 仅在无法使用 Hook 的场合 |
作为原生 iOS 开发者,你可以把 Dimensions 看作 RN 中的 UIScreen,把 useWindowDimensions 看作会自动处理 viewWillTransition 的便利封装。在大多数布局场景下,Flexbox 已经足够强大,你甚至不需要手动获取屏幕宽度;只有在需要精确计算尺寸(如网格布局、卡片宽度)或实现全屏覆盖时,才会用到 Dimensions。