ReactNative如何适配750的设计稿?

21 阅读2分钟

到底是多少宽度

众所周不知react-native的样式是没有单位的,那么我写了一个样式如下到底是多少宽度(满脸问号)

const LoginStyles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'pink'
  },
  title: {
    textAlign: 'center',
    fontWeight: 700,
    fontSize: 28, // 字号到底是多少
    marginBottom: 20
  },
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    padding: 5,
    borderRadius: 10
  }
})

解决方案来了

查询各种资料发现一个库react-native-size-matters可以解决这个问题,然后咔咔一顿写

import {
  scale,
} from 'react-native-size-matters'

const LoginStyles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'pink'
  },
  title: {
    textAlign: 'center',
    fontWeight: 700,
    fontSize: scale(28),
    marginBottom: scale(20)
  },
  input: {
    borderWidth: scale(1),
    borderColor: '#ccc',
    padding: scale(5),
    borderRadius: scale(10)
  }
})

哎呦!被骗了!

心里美滋滋,写完和设计稿一对比! 哎呦! 草泥打野!这效果和设计稿真是一模不一样!崩溃!!!!翻开react-native-size-matters源码一看,顿时一阵##@#@@#@#@(鸟语花香)内置的设计稿宽度竟然是300,这怎么可以必须魔改一番!

嘿嘿!这才像正版的嘛!

import { Dimensions } from 'react-native'
import {
  scale,
  verticalScale,
  moderateScale
} from 'react-native-size-matters'

// 设计稿基准宽度(750px)
const DESIGN_WIDTH = 750
// 库默认的基准宽度(600px)
const DEFAULT_DESIGN_WIDTH = 600

// 获取设备屏幕宽度
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window')

/**
 * 适配750设计稿的水平尺寸
 * @param {number} size 设计稿上的px值
 * @returns 适配后的尺寸
 */
export const scale750 = (size: number) => {
  // 方法1:基于库的scale函数转换(推荐,复用库的逻辑)
  // return rnsmScale(size * (DEFAULT_DESIGN_WIDTH / DESIGN_WIDTH));

  // 方法2:直接计算(和方法1等价,更直观)
  return size * (SCREEN_WIDTH / DESIGN_WIDTH)
}

/**
 * 适配750设计稿的垂直尺寸
 * @param {number} size 设计稿上的px值
 * @returns 适配后的尺寸
 */
export const verticalScale750 = (size: number) => {
  // return verticalScale(size * (DEFAULT_DESIGN_WIDTH / DESIGN_WIDTH))

  // 直接计算等价写法:
  return size * (SCREEN_HEIGHT / (DESIGN_WIDTH * (SCREEN_HEIGHT / SCREEN_WIDTH)));
}

/**
 * 适配750设计稿的温和缩放(字体/关键元素推荐)
 * @param {number} size 设计稿上的px值
 * @param {number} factor 缩放系数(0-1,越小越接近固定尺寸)
 * @returns 适配后的尺寸
 */
export const moderateScale750 = (size: number, factor = 0.5) => {
  return moderateScale(size * (DEFAULT_DESIGN_WIDTH / DESIGN_WIDTH), factor)
}

// 监听屏幕旋转,适配横屏(可选)
Dimensions.addEventListener('change', ({ window }) => {
  // 库内部会自动更新设备尺寸,无需额外操作,封装的scale750/verticalScale750/moderateScale750会自动生效
})

页面中验证一番

import { scale750 } from '@/tools'

const LoginStyles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'pink'
  },
  title: {
    textAlign: 'center',
    fontWeight: 700,
    fontSize: scale750(28),
    marginBottom: scale750(20)
  },
  input: {
    borderWidth: scale750(1),
    borderColor: '#ccc',
    padding: scale750(5),
    borderRadius: scale750(10)
  }
})

打开页面一看和设计稿一模一样!哈哈!道爷我成了! ~~~