RN 中的Dimensions

Dimensions 是 React Native 提供的一个 核心 API 模块,用于获取设备的屏幕宽高、窗口尺寸或特定元素的尺寸。它的作用类似于 iOS 原生中的 UIScreen.main.boundsUIWindow 的尺寸信息。

基本用法

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,但已废弃。

常见使用场景

  1. 响应式布局:根据屏幕宽度动态计算卡片宽度或字体大小。
  2. 全屏组件:例如 Modal、全屏图片预览,需要占满整个窗口。
  3. 自定义横竖屏适配:监听尺寸变化后重新布局(但 RN 的 Flexbox 通常会自动适配,不需要手动处理)。
  4. 计算元素位置:配合 onLayout 事件,获取某个组件相对于屏幕的绝对位置。

重要注意事项

1. 初始值的获取时机

在组件首次渲染时,Dimensions.get('window') 会返回正确的值。但如果组件在屏幕旋转后才挂载,获取到的也是最新的正确值。不过,如果你的组件需要在尺寸变化后立即计算某些布局(如动画起始位置),建议在 useEffect 中读取最新值并设置状态。

2. 与 useWindowDimensions 的对比

React Native 还提供了一个 HookuseWindowDimensions,它会在屏幕尺寸变化时自动触发组件重新渲染,无需手动监听。

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容