React Native 响应式字体大小
Posted
技术标签:
【中文标题】React Native 响应式字体大小【英文标题】:React Native Responsive Font Size 【发布时间】:2016-02-11 06:04:21 【问题描述】:我想问一下如何响应原生句柄或响应式字体。例如在 iphone 4s 我有 fontSize: 14,而在 iphone 6 我有 fontSize: 18.
【问题讨论】:
如果有人正在寻找完全禁用字体缩放的方法,请使用Text.defaultProps.allowFontScaling=false
@CoderDave 这太棒了!
如果你想要基于屏幕大小的相对字体大小而不是精确的字体大小,你可以试试npmjs.com/package/react-native-responsive-dimensions,它会根据设备的屏幕大小自动调整你的字体大小
【参考方案1】:
因为响应式单元目前在 react-native 中不可用,我想说你最好的办法是检测屏幕尺寸,然后使用它来推断设备类型并有条件地设置 fontSize。
你可以这样写一个模块:
function fontSizer (screenWidth)
if(screenWidth > 400)
return 18;
else if(screenWidth > 250)
return 14;
else
return 12;
您只需要查看每个设备的默认宽度和高度。如果在设备改变方向时宽度和高度被翻转,您可能可以使用纵横比,或者只计算两个维度中较小的一个来计算宽度。
此module 或this one 可以帮助您查找设备尺寸或设备类型。
【讨论】:
我已经安装了 react-native-device 但是当我运行应用程序时它给了我一个“无法解析模块维度”的错误 听起来你需要确保为模块使用正确版本的 RN 我正在使用最新版本的 React Native :) 我认为它目前不受支持? 可能...也许尝试删除您的 node_modules 文件夹并重新npm install
【参考方案2】:
您可以使用PixelRatio
例如:
var React = require('react-native');
var StyleSheet, PixelRatio = React;
var FONT_BACK_LABEL = 18;
if (PixelRatio.get() <= 2)
FONT_BACK_LABEL = 14;
var styles = StyleSheet.create(
label:
fontSize: FONT_BACK_LABEL
);
编辑:
另一个例子:
import Dimensions, Platform, PixelRatio from 'react-native';
const
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
= Dimensions.get('window');
// based on iphone 5s's scale
const scale = SCREEN_WIDTH / 320;
export function normalize(size)
const newSize = size * scale
if (Platform.OS === 'ios')
return Math.round(PixelRatio.roundToNearestPixel(newSize))
else
return Math.round(PixelRatio.roundToNearestPixel(newSize)) - 2
用法:
fontSize: normalize(24)
您可以更进一步,允许在每个 <Text />
组件上使用预定义大小的大小。
例子:
const styles =
mini:
fontSize: normalize(12),
,
small:
fontSize: normalize(15),
,
medium:
fontSize: normalize(17),
,
large:
fontSize: normalize(20),
,
xlarge:
fontSize: normalize(24),
,
;
【讨论】:
你在哪里使用了你的 const 比例? 这似乎没有任何作用。迷你总是 === 12 为什么非 ios 设备要减去 2? @chinloong 谢谢这很好用,但是为什么在 android 上是 -2? 它不起作用,例如,对于 iPhone 12 mini 和 iPhone X,因为它们都有宽度 375 和像素比 3。虽然很明显,布局和字体大小应该注意差异.【参考方案3】:看看我写的库:https://github.com/tachyons-css/react-native-style-tachyons
它允许您在启动时指定一个 root-fontSize (rem
),您可以根据您的 PixelRatio
或其他设备特性进行设置。
然后你会得到与你的 rem
相关的样式,不仅是 fontSize,还有 paddings 等:
<Text style=[s.f5, s.pa2, s.tc]>
Something
</Text>
扩展:
f5
始终是您的基本字体大小
pa2
为您提供相对于基本字体大小的填充。
【讨论】:
【参考方案4】:我们使用我们编写的简单、直接、可扩展的 utils 函数:
import Dimensions from 'react-native';
const width, height = Dimensions.get('window');
//Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const scale = size => width / guidelineBaseWidth * size;
const verticalScale = size => height / guidelineBaseHeight * size;
const moderateScale = (size, factor = 0.5) => size + ( scale(size) - size ) * factor;
export scale, verticalScale, moderateScale;
为您节省一些时间来做许多 ifs。您可以在my blog post 上阅读更多相关信息。
编辑:我认为将这些函数提取到他们自己的 npm 包中可能会有所帮助,我还在包中包含了
ScaledSheet
,这是StyleSheet
的自动缩放版本。
你可以在这里找到它:react-native-size-matters。
【讨论】:
谢谢,使用这个工具的最佳方案是什么?我的意思是在哪里使用scale、verticaleScale和moderateScale? 我在几乎所有需要缩放的东西上都使用了中等缩放,比如字体大小、边距、图像和 Svg 大小(对于布局我使用 flex),因为 imo 缩放不应该是线性的,但这是个人喜好问题.如果您想获得线性结果,则主要使用比例,并在容器高度等内容上使用verticalScale。 过度使用在性能方面可以吗?【参考方案5】:我通过执行以下操作设法克服了这个问题。
为当前视图选择您喜欢的字体大小(确保 它看起来很适合您正在使用的当前设备 模拟器)。
import Dimensions from 'react-native'
并定义宽度
像这样在组件之外:let width = Dimensions.get('window').width;
现在 console.log(width) 并把它写下来。如果你的字体好看 例如,尺寸为 15,宽度为 360,然后取 360 和 除以 15 (= 24)。这将是重要的价值 会适应不同的尺寸。
在您的样式对象中使用此数字,如下所示:textFontSize: fontSize = width / 24 ,...
现在你有了一个响应式字体大小。
【讨论】:
嘿,它真的有效吗? f1 = width/ (width/size) 这不行吗? 我最终使用了react-native-text
。
c0dezer019.medium.com/thank-you-3824cb7b886c 和 medium.com/nerd-for-tech/… 这与@walter 相同,加上四舍五入等。谢谢老兄。
是的,我的解决方案并不完美,但它适用于我的用例!【参考方案6】:
你可以使用这样的东西。
var height, width = Dimensions.get('window'); var textFontSize = 宽度 * 0.03;
inputText:
color : TEXT_COLOR_PRIMARY,
width: '80%',
fontSize: textFontSize
希望这有助于在不安装任何第三方库的情况下。
【讨论】:
0.03 是从哪里来的? 它会响应吗?【参考方案7】:我只是使用屏幕大小的比例,这对我来说很好。
const width, height = Dimensions.get('window');
// Use iPhone6 as base size which is 375 x 667
const baseWidth = 375;
const baseHeight = 667;
const scaleWidth = width / baseWidth;
const scaleHeight = height / baseHeight;
const scale = Math.min(scaleWidth, scaleHeight);
export const scaledSize =
(size) => Math.ceil((size * scale));
测试
const size =
small: scaledSize(25),
oneThird: scaledSize(125),
fullScreen: scaledSize(375),
;
console.log(size);
// iPhone 5s
small: 22, oneThird: 107, fullScreen: 320
// iPhone 6s
small: 25, oneThird: 125, fullScreen: 375
// iPhone 6s Plus
small: 28, oneThird: 138, fullScreen: 414
【讨论】:
这是否意味着您必须使用 iPhone 6 模拟器,并且根据它在那里的外观,它在其他设备上看起来也不错? @WalterMonecke 在我的情况下是的。您也可以适应使用其他模拟器作为基础。【参考方案8】:我最近遇到了这个问题,最终使用了react-native-extended-stylesheet
您可以根据屏幕尺寸设置rem
值和附加尺寸条件。根据文档:
// component
const styles = EStyleSheet.create(
text:
fontSize: '1.5rem',
marginHorizontal: '2rem'
);
// app entry
let height, width = Dimensions.get('window');
EStyleSheet.build(
$rem: width > 340 ? 18 : 16
);
【讨论】:
【参考方案9】:import Dimensions from 'react-native';
const width, fontScale = Dimensions.get("window");
const styles = StyleSheet.create(
fontSize: idleFontSize / fontScale,
);
fontScale
根据您的设备获取规模。
【讨论】:
fontscale 在我正在使用的 Android Emulator 4_WVGA_Nexus_S_API 虚拟设备上只返回 1。【参考方案10】:我们可以使用 flex 布局并使用 adjustsFontSizeToFit=true 来获得响应式字体大小。并且文本会根据容器的大小进行调整。
<Text
adjustsFontSizeToFit
style=styles.valueField>value
</Text>
但在样式中,您还需要设置一个字体大小,然后adjustsFontSizeToFit 才会起作用。
valueField:
flex: 3,
fontSize: 48,
marginBottom: 5,
color: '#00A398',
,
【讨论】:
【参考方案11】:adjustsFontSizeToFit
和 numberOfLines
为我工作。他们将长电子邮件调整为 1 行。
<View>
<Text
numberOfLines=1
adjustsFontSizeToFit
style=textAlign:'center',fontSize:30
>
this.props.email
</Text>
</View>
【讨论】:
根据文档 'adjustsFontSizeToFit' 仅适用于 iOS 它也适用于 android @mdehghani 对我也有用,这篇文章应该被接受为正确答案! 我可以确认它适用于 Android 和 iOS!这正是我一直在寻找的。应该是正确答案。【参考方案12】:为什么不使用PixelRatio.getPixelSizeForLayoutSize(/* size in dp */);
,它和Android 中的pd
单位一样。
【讨论】:
【参考方案13】:需要这种方式我用过这个,效果很好。
react-native-responsive-screen npm install react-native-responsive-screen --save
就像我有一台 1080x1920 的设备
The vertical number we calculate from height **hp**
height:200
200/1920*100 = 10.41% - height:hp("10.41%")
The Horizontal number we calculate from width **wp**
width:200
200/1080*100 = 18.51% - Width:wp("18.51%")
它适用于所有设备
【讨论】:
【参考方案14】:一种稍微不同的方法对我有用:-
const normalize = (size: number): number =>
const scale = screenWidth / 320;
const newSize = size * scale;
let calculatedSize = Math.round(PixelRatio.roundToNearestPixel(newSize))
if (PixelRatio.get() < 3)
return calculatedSize - 0.5
return calculatedSize
;
请参考Pixel Ratio,因为这可以让您更好地根据设备密度设置功能。
【讨论】:
【参考方案15】:我通常用这个:
import React from 'react';
import View, Text, StyleSheet, Dimensions from 'react-native';
var heightY = Dimensions.get("window").height;
export default function App()
return (
<View style=styles.container>
<Text style=styles.textStyle>fontSize heightY * 0.014</Text>
</View>
)
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
,
textStyle:
fontSize: heightY * 0.014,
)
我们的想法是根据屏幕高度获取fontSize
。计算示例:
// Height 785,.. -> fontSize = 11
// Height 1000 -> fontSize = 14
// Height 1285,.. -> fontSize = 18
如果您希望它取决于您的屏幕宽度,您也可以尝试使用它:
var widthX = Dimensions.get("window").width;
【讨论】:
以上是关于React Native 响应式字体大小的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React Native for Android 中调整字体大小以适应视图?
具有不同字体大小(首字母,首字母)的 react-native 嵌套文本