Dimensions 是 React Native 提供的一個 核心 API 模塊,用于獲取設(shè)備的屏幕寬高、窗口尺寸或特定元素的尺寸。它的作用類似于 iOS 原生中的 UIScreen.main.bounds 或 UIWindow 的尺寸信息。
基本用法
import { Dimensions } from 'react-native';
// 獲取整個屏幕的尺寸(包括狀態(tài)欄、導航欄占用的區(qū)域)
const screen = Dimensions.get('window');
console.log(screen.width, screen.height); // 例如:375, 812
// 獲取應(yīng)用窗口的尺寸(在某些設(shè)備上可能與 screen 相同,但在分屏或折疊屏下會不同)
const window = Dimensions.get('window'); // 常用這個
// 解構(gòu)賦值,并重命名變量
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
注意:在 React Native 中,
Dimensions.get('window')返回的是應(yīng)用可用的窗口尺寸(即除去系統(tǒng)狀態(tài)欄、底部安全區(qū)等之外的區(qū)域,但具體行為取決于平臺和 RN 版本)。大多數(shù)情況下直接用'window'即可,它與UIScreen.main.bounds最接近。
與 iOS 原生的對比
| 場景 | React Native | iOS 原生 |
|---|---|---|
| 獲取屏幕尺寸 | Dimensions.get('window') |
UIScreen.main.bounds |
| 監(jiān)聽尺寸變化(旋轉(zhuǎn)/多窗口) | Dimensions.addEventListener('change', handler) |
viewWillTransition(to:with:) 或 UIContentSizeCategory 通知 |
| 獲取邏輯像素(points) | 直接返回的數(shù)字就是邏輯像素(dp/points) | 原生中的 bounds.size 也是 points |
| 物理像素 | 需要用 PixelRatio.getPixelSizeForLayoutSize(size)
|
UIScreen.main.scale |
監(jiān)聽屏幕尺寸變化
當設(shè)備旋轉(zhuǎn)、iPad 分屏或折疊屏折疊時,Dimensions 的值會變化。你需要監(jiān)聽變化并更新 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(() => {
// 添加監(jiān)聽器
const subscription = Dimensions.addEventListener('change', ({ window, screen }) => {
setScreenWidth(window.width);
// 可以在這里強制重新計算樣式或重新渲染
});
// 清理監(jiān)聽器
return () => subscription?.remove();
}, []);
return (
<View style={{ width: screenWidth, backgroundColor: 'lightblue' }}>
<Text>當前屏幕寬度: {screenWidth}</Text>
</View>
);
};
注意:在較新版本的 RN 中(0.65+),推薦使用
addEventListener返回的訂閱對象調(diào)用remove()。舊版本中可能使用Dimensions.removeEventListener,但已廢棄。
常見使用場景
- 響應(yīng)式布局:根據(jù)屏幕寬度動態(tài)計算卡片寬度或字體大小。
- 全屏組件:例如 Modal、全屏圖片預覽,需要占滿整個窗口。
- 自定義橫豎屏適配:監(jiān)聽尺寸變化后重新布局(但 RN 的 Flexbox 通常會自動適配,不需要手動處理)。
-
計算元素位置:配合
onLayout事件,獲取某個組件相對于屏幕的絕對位置。
重要注意事項
1. 初始值的獲取時機
在組件首次渲染時,Dimensions.get('window') 會返回正確的值。但如果組件在屏幕旋轉(zhuǎn)后才掛載,獲取到的也是最新的正確值。不過,如果你的組件需要在尺寸變化后立即計算某些布局(如動畫起始位置),建議在 useEffect 中讀取最新值并設(shè)置狀態(tài)。
2. 與 useWindowDimensions 的對比
React Native 還提供了一個 Hook:useWindowDimensions,它會在屏幕尺寸變化時自動觸發(fā)組件重新渲染,無需手動監(jiān)聽。
import { useWindowDimensions } from 'react-native';
const { width, height } = useWindowDimensions();
// 直接使用,尺寸變化時組件自動更新
推薦優(yōu)先使用 useWindowDimensions,它更簡潔且不易出錯。
3. 折疊屏/多窗口支持
在 iPad 多任務(wù)分屏、Android 折疊屏或 Chrome OS 中,Dimensions.get('window') 會返回當前應(yīng)用窗口的實際大小。你需要監(jiān)聽變化并重新布局,否則部分內(nèi)容可能被裁剪或留白。
4. 單位是“點”(points)
返回的數(shù)字是邏輯像素,與 iOS 的 UIScreen.main.bounds.width 含義完全一致。如果需要物理像素(例如繪制 1 物理像素的細線),可以使用 PixelRatio.getPixelSizeForLayoutSize(1)。
總結(jié)
| API | 作用 | 推薦度 |
|---|---|---|
Dimensions.get('window') |
同步獲取當前窗口尺寸 | 可用于類組件或非 React 上下文 |
useWindowDimensions() |
Hook,自動響應(yīng)尺寸變化 | 優(yōu)先使用 |
Dimensions.addEventListener |
手動監(jiān)聽變化 | 僅在無法使用 Hook 的場合 |
作為原生 iOS 開發(fā)者,你可以把 Dimensions 看作 RN 中的 UIScreen,把 useWindowDimensions 看作會自動處理 viewWillTransition 的便利封裝。在大多數(shù)布局場景下,F(xiàn)lexbox 已經(jīng)足夠強大,你甚至不需要手動獲取屏幕寬度;只有在需要精確計算尺寸(如網(wǎng)格布局、卡片寬度)或?qū)崿F(xiàn)全屏覆蓋時,才會用到 Dimensions。