React Native - PixelRatio的使用(像素密度、最细边框、合适的图片尺寸)
在 React Native 开发中,使用的尺寸单位是 pt,但由于移动设备的像素密度不一样,即 1pt 对应的像素个数是不一样的。为此,React Native 提供了 PixelRatio API 来告知开发者当前设备的像素密度。
一、PixelRatio介绍
PixelRatio 提供了一些静态方法供我们使用,具体如下:
1,get()
获取像素密度,不同设备的返回值如下:
- 1 :mdpi Android devices(160 dpi)
- 1.5:hdpi Android devices(240 dpi)
- 2 :iphone 4,4s,5,5s,5c,6,6s,7
xhdip Android devices(320 dpi) - 3 :iphone 6 plus,6s plus,7 plus
xxhdpi Android devices(480 dpi) - 3.5:Nexus 6
2,getPixelSizeForLayoutSize(number)
将一个布局尺寸(dp)转换为像素尺寸(px)。注意:这个一定会返回一个整数数值。其内部的实现很简单:
我们的应用可能运行在普通设备上,也能运行在高清设备上。如果要加载并显示一张图片,在普通设备上我们可能只需要一张普通分辨率的图片即可。而到了高清设备上,就需要去加载更高分辨率的图片。
function getPixelSizeForLayoutSize(layoutSize){ return Math.round(layoutSize * PixelRatio.get()); }
3,getFontScale()
(1)返回字体大小缩放比例。这个比例可以用于计算绝对的字体大小,所以很多深度依赖字体大小的组件需要用此函数的结果进行计算。
(2)如果没有设置字体大小,它会直接返回设备的像素密度。
(3)目前这个函数仅仅在 Android 设备上实现了,它会体现用户选项里的“设置 > 显示 > 字体大小”。在 iOS 设备上它会直接返回默认的像素密度。
二、PixelRatio的使用样例
1,绘制最细边框、线条
使用 borderWidth:1/PixelRatio.get() 可以获取最细的边框线条尺寸(1像素)。下面样例中,上下两个矩形分别使用的是 1pt 边框,和最细的 1px 边框。
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, PixelRatio } from 'react-native'; //默认应用的容器组件 class App extends Component { render() { return ( <View style={styles.container}> <View style={styles.item1}><Text>1pt边框</Text></View> <View style={styles.item2}><Text>1px边框</Text></View> </View> ); } } //样式定义 const styles = StyleSheet.create({ container:{ flex: 1, marginTop:25 }, item1:{ borderWidth:1, borderColor:'orange', height:40, marginBottom:20 }, item2:{ borderWidth:1/PixelRatio.get(), borderColor:'orange', height:40 } }); AppRegistry.registerComponent('HelloWorld', () => App);
舍入操作是否会造成元素模糊?
- 在 iOS 开发时,我们可以为元素指定有任意精度的位置和尺寸,例如 29.674825。但是,最终的物理显示就只有一个固定的像素值,这些最终都会由系统进行扩展处理。同时由于反锯齿技术,可能会使得元素看起来很模糊。所以为了避免生成模糊的像素,就要求开放人员手动进行舍入操作。
同时还要注意不断的积累舍入误差。否则一个舍入误差会造成致命性的错误,因为一个像素边界可能会消失或者变成两倍那么大。具体参考我的这篇文章:Swift - 正确绘制1像素的线条(附样例) - 而在 React Native 里,在 JS 和布局引擎里的一切值都是以一个任意精度的数来进行工作的。这只会发生在当在为主线程里我们进行舍入的原生元素设定任意位置和尺寸的时候。同时,舍入操作是针对根而不是父母完成的,这又一次避免了累积舍入误差。
所以 React Native 是不会出现这中模糊现象,大大减轻了开放人员的负担。
2,获取一个正确大小的图像
我们的应用可能运行在普通设备上,也能运行在高清设备上。如果要加载并显示一张图片,在普通设备上我们可能只需要一张普通分辨率的图片即可。而到了高清设备上,就需要去加载更高分辨率的图片。
究竟要请求多大尺寸的图片,这个可以使用 PixelRatio.getPixelSizeForLayoutSize 来实现,下面是一个简单的代码示例。
var image = getImage({ width: PixelRatio.getPixelSizeForLayoutSize(200), height: PixelRatio.getPixelSizeForLayoutSize(100), }); <Image source={image} style={{width: 200, height: 100}} />上面代码表示,如果我们要在屏幕上摆放一个宽 200,高 100 的图片,那么首先要准备多个分辨率尺寸的图。