iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Mobile Development

30天React Native之旅:從入門到活用系列 第 19

Day 19:PixelRatio的使用

  • 分享至 

  • xImage
  •  

在 React Native 中,使用的單位尺寸是獨立像素(density-independent pixels)簡稱dp,不是真實的物理像素 physical pixels(px)。dp是一種抽象單位,用於幫助確保界面在不同密度的螢幕上保持一致的尺寸。舉例來說,如果設定一個字體大小為16dp,實際在屏幕上的大小可能會根據設備的像素密度而有所不同。而React Native提供了PixelRatio,可以讓我們精確的處理像素轉換。

方法

  • get():獲取裝置的像素比例(px和dp之間的比例)。

    const ratio = PixelRatio.get();
    console.log(ratio);  // 例如:3
    

    常見比例

    • 1x (ratio = 1):
      傳統的低解析度裝置
      一些早期的智慧型手機和平板
    • 1.5x (ratio = 1.5):
      中等解析度裝置
    • 2x (ratio = 2):
      高解析度裝置
      例如:iPhone 4, 4s, 5, 5c, 5s, SE, 6, 7, 8, etc.
    • 3x (ratio = 3):
      更高的解析度裝置
      例如:iPhone X, XS, 11 Pro, 12 Pro etc.
    • 3.5x, 4x ...:
      超高解析度裝置
      一些新型的裝置或某些特定裝置
  • getFontScale(): 裝置上字體縮放比例。
    返回 1 表示使用者沒有在系統上調整字體大小。

  • getPixelSizeForLayoutSize(number): dp轉換為px。
    其實就是pixelratio.get() * 你輸入的number

  • roundToNearestPixel: 將px值四捨五入到最接近的dp值。

應用範例

  • 根據裝置的像素比率選擇合適解析度的圖片:

    const App = () => {
        let imageSrc;
        const ratio = PixelRatio.get();
    
        if (ratio <= 1) {
          imageSrc = require('./path/to/image@1x.png');
        } else if (ratio <= 2) {
          imageSrc = require('./path/to/image@2x.png');
        } else {
          imageSrc = require('./path/to/image@3x.png');
        }
    
        return (
          <Image source={imageSrc} style={{width: 100, height: 100}} />
        );
    }
    

    我們使用PixelRatio.get()獲取裝置的像素比例。根據該比例,我們選擇相應的圖片資源,然後使用Image組件顯示該圖片。

  • 細邊框:
    在一些情境中,我們可能想要一個非常細的邊框,但由於像素密度的差異,直接設定 borderWidth: 1 沒辦法達到期望的效果。這時就可以使用 PixelRatio 解決這個問題:

        const styles = StyleSheet.create({
        thinBorder: {
          borderWidth: 1 / PixelRatio.get(),
        },
      });
    

    我們用1/PixelRatio.get() 獲取最細邊框(1px)

    效果比較:

    <View style={styles.thinBorder}>
    <View style={styles.normalBorder} />
    
    thinBorder: {
      width: 100,
      height: 100,
      borderColor: "#000",
      borderWidth: 1 / PixelRatio.get(),
      marginBottom: 10,
    },
    normalBorder: {
      width: 100,
      height: 100,
      borderColor: "#000",
      borderWidth:1,
    }
    

    iPhone 14 Pro:上方1px,下方1dp
    https://ithelp.ithome.com.tw/upload/images/20231004/20103365gALYk7Jh3Y.png

  • 更細緻的字體比例控制:
    上一篇<Text/>有提到allowFontScaling屬性可以讓字體隨著系統比例放大,而用PixelRatio,我們可以更精確地控制並調整字體的大小。

    例如,透過PixelRatio獲取系統的字體縮放比例,接著再依此比例調整設計稿中所定義的基礎字體大小。

    import React from 'react';
    import { View, Text, PixelRatio, StyleSheet } from 'react-native';
    
    export default function App() {
      // 獲取裝置的字體縮放比例
      const fontScale = PixelRatio.getFontScale();
    
      // 設計稿中的基礎字體大小
      const designFontSize = 20;
    
      // 根據字體縮放比例調整字體大小
      const adjustedFontSize = designFontSize * fontScale;
    
      return (
        <View style={styles.container}>
          <Text style={{ fontSize: adjustedFontSize }}>
            我是應用中的標題
          </Text>
          <Text style={styles.body}>
            以下是一些內容...
          </Text>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      },
      body: {
        marginTop: 20,
        fontSize: 16,
      },
    });
    

同場加映,圖片比例隨螢幕寬度變化

除了用PixelRatio選取合適解析度圖片外,如果想要圖片自適應依照螢幕寬度調整比例,我們可以用React Native的Dimensions。透過Dimensions獲取螢幕的尺寸來動態的調整圖片大小。

例如:有一張寬440px、高330px的圖片,我們希望圖片寬100%,高度保持比例:

import React from 'react';
import { View, Image, StyleSheet, Dimensions } from 'react-native';

export default function App() {
  const screenWidth = Dimensions.get('window').width;
  const imageRatio = 440 / 330;  // 圖片的原始寬高比
  const imageHeight = screenWidth / imageRatio;

  return (
    <View style={styles.container}>
      <Image 
        source={require('./src/Taipei_101_Mall_view_2019.jpg')} 
        style={{ width: screenWidth, height: imageHeight }}
        resizeMode="contain"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  }
});

在此範例中,我們首先用Dimensions獲取螢幕的寬度。接著,利用圖片的原始寬和高計算其高寬比,再根據這比例計算新的高度。這樣,不論裝置的尺寸如何,圖片都將保持原始的高寬比。


上一篇
Day 18:認識<Text />組件
下一篇
Day 20:React Native的滾動組件與無限滾動
系列文
30天React Native之旅:從入門到活用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言