如何在 React Native for Android 中调整字体大小以适应视图?

Posted

技术标签:

【中文标题】如何在 React Native for Android 中调整字体大小以适应视图?【英文标题】:How to adjust font size to fit view in React Native for Android? 【发布时间】:2018-06-08 15:57:35 【问题描述】:

如何在 react native 中使文本的字体大小在视图内自动更改?

我有不同长度的文本,其中一些不适合视图,因此减小了字体大小。我检查了文档,发现this 但它仅适用于 ios,我需要它用于 android

它是否适用于其他组件,例如按钮和 touchableopacity?

【问题讨论】:

React Native Responsive Font Size的可能重复 这不是那个问题的重复。上一个问题询问有关根据屏幕大小设置字体大小的问题。这个问题是关于让特定文本组件的字体大小根据文本缩放以适应其父视图。想象一下来自 Web 服务的动态文本的用例,您希望它填充特定大小的框,但无法预测字符串的长度。 ***.com/questions/47657294/…的可能重复 【参考方案1】:

对我有用的一点改进的 Jeffy Lee 代码

const AdjustLabel = (
  fontSize, text, style, numberOfLines
) => 
  const [currentFont, setCurrentFont] = useState(fontSize);

  return (
    <Text
      numberOfLines= numberOfLines 
      adjustsFontSizeToFit
      style= [style,  fontSize: currentFont ] 
      onTextLayout= (e) => 
        const  lines  = e.nativeEvent;
        if (lines.length > numberOfLines) 
          setCurrentFont(currentFont - 1);
        
       
    >
       text 
    </Text>
  );
;

【讨论】:

adjustsFontSizeToFit 完美适用于android @miteshkalal 并非总是如此。仅适用于一些较新的版本。在旧版本中,除了不更改字体大小外,还可能会冻结应用程序并且如果有最大宽度则不会应用省略号。【参考方案2】:

试试这个方法。考虑根据屏幕宽度设置字体大小如下

width: Dimensions.get('window').width

所以在你的风格中尝试进行百分比计算以使字体大小适合屏幕

style=
  text:
     fontSize:0.05*width
  

这将适用于所有屏幕(Android 和 IOS)

【讨论】:

0.05 来自哪里? @c4k 这只是一个口粮,将其设置为适合您的屏幕,您将获得适用于所有屏幕的此解决方案 这不会自动减小较长文本的字体大小以适应特定的视图宽度,它只是根据您的屏幕宽度将所有字体设置为特定大小。这不是问题的答案。 同意@Jenever - 这不能回答 OP 的问题。它解决了一个完全不同的问题。 这很有用,但不回答 OP 的要求【参考方案3】:

试试这个方法。

我使用了onLayout的方法来实现这个。

首先,我将我的 Text 视图包裹在一个固定大小的 View 中,然后我为这两个视图实现了 onLayout,这样我就可以获得固定大小的 View 的高度和 Text 视图的高度。

接下来,如果 Text 视图所需的高度大于 View 的高度,我们会减小 Text 视图的字体大小,直到高度适合我们的 View。

在测试代码中,我做了2个Views,1个粉红色,1个黄色背景,粉红色View内Text的字体大小将调整以适应View,黄色Text将保持相同的字体大小。

import React,  useState, useEffect  from 'react';
import  StyleSheet, Text, View  from 'react-native';

export default function App() 
  const [size, setSize] = useState(20)
  const [viewHeight, setViewHeight] = useState(0)
  const [textHeight, setTextHeight] = useState(0)

  useEffect(() => 
    if (textHeight > viewHeight) 
      setSize(size - 1) // <<< You may adjust value 1 to a smaller value so the text can be shrink more precisely
    
  , [textHeight])

  return (
    <View style=styles.container>
      <View
        style=
          margin: 20,
          backgroundColor: 'pink',
          width: 200,
          height: 200
        
        onLayout=(event) => 
          var  x, y, width, height  = event.nativeEvent.layout;
          setViewHeight(height)
        
      >
        <Text
          style=
            fontSize: size,
          
          onLayout=(event) => 
            var  x, y, width, height  = event.nativeEvent.layout;
            setTextHeight(height)
          
        >
          Gemma is a middle grade novel that follows a curious explorer and her ring-tailed lemur, Milo, 
          as they hunt for the “most greatest treasure in the world”. Solving riddles, battling a bell-wearing 
          jaguar, and traveling the Eight Seas, Gemma’s adventures take her from a young girl to a brave captain, 
          whose only limits are the stars.
        </Text>
      </View>

      <View
        style=
          margin: 20,
          backgroundColor: 'yellow',
          width: 200,
          height: 200
        
      >
        <Text
          style=
            fontSize: 20
          
        >
          Gemma is a middle grade novel that follows a curious explorer and her ring-tailed lemur, Milo, 
          as they hunt for the “most greatest treasure in the world”. Solving riddles, battling a bell-wearing 
          jaguar, and traveling the Eight Seas, Gemma’s adventures take her from a young girl to a brave captain, 
          whose only limits are the stars.
        </Text>
      </View>
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  ,
);

您可能会注意到,当字体大小减小时,粉红色文本的字体有一个缩小的动画,我建议您可以将文本不透明度初始化为 0,然后在字体调整完成后将其设置为 1,这样用户就不会看到丑陋的动画了.

【讨论】:

【参考方案4】:

编辑

我最近面临一项更具挑战性的任务。任务是在相同的视图(每个视图一个词)中适应多个不同长度的单词(例如:Plane 和 Truck 具有相同的字符数,但 Truck 在以相同字体大小编写时比 ​​Plane 长。)尺寸。我使用 React Native Animated 库来实现这一点。 输入词 -> Plane, Truck, Bus, Car, Cab

    使用 Text 组件呈现所有给定的单词,使用固定的字体大小,最好是更大的字体大小,超过最长单词所需的宽度。 使用文本组件的onLayout函数找到最长单词的宽度和高度(高度已经相似)。 计算沿 X 轴和 Y 轴的比例因子(由于步骤 1 中的假设而小于 1。)以适应固定视图中的最大单词并取这 2 个中的最小值。 然后渲染 Text 组件(具有相同的字体大小)中的每个单词,该组件用 View 组件包裹,刚好适合 Text,并使用 transform prop 以相同的比例因子缩放每个 View。

我实现了上述想法,因为不断减小字体大小直到使用 onLayout 的单词适合视图对用户来说是可见的,无论我在算法运行期间使用哪种技巧来隐藏它。我为此发布了一个 npm 包:https://www.npmjs.com/package/@chamodanethra/react-native-fitted-text

【讨论】:

【参考方案5】:

在我的 React Native 应用程序中,我在调整视图大小的文本数量(用户输入字符串到当前限制为 30 个字符的输入字段中)时遇到了类似的问题。我注意到已经为 iOS 实现了一些属性:adjustsFontSizeToFit minimumFontScale=.4 但是 Android 目前没有这样的方法可用。

注意:对我有用但可能不是“最好”的解决方案!

目前,我使用的是嵌套三元运算符:

fontSize: this.props.driverName.length > 12 && 
this.props.driverName.length < 20 ? heightPercentageToDP('2%') : 
this.props.driverName.length > 20 && this.props.driverName.length < 40 
? heightPercentageToDP('1.75%') : heightPercentageToDP('2.25%')

用外行的话来说,上面的三元检查使用的字符范围,并根据范围将 fontSize 修改为视图内的 '%'。方法:heightPercentageToDP 是我用来根据手机屏幕的 DP 将大小转换为 '%' 的函数(这样它在平板电脑或手机上都有响应)。

heightPercentageToDP 代码片段:

    import  Dimensions, PixelRatio  from "react-native";
    const widthPercentageToDP = widthPercent => 
    const screenWidth = Dimensions.get("window").width;
    // Convert string input to decimal number
    const elemWidth = parseFloat(widthPercent);
    return PixelRatio.roundToNearestPixel((screenWidth * elemWidth) / 100);
    ;
    const heightPercentageToDP = heightPercent => 
    const screenHeight = Dimensions.get("window").height;
    // Convert string input to decimal number
    const elemHeight = parseFloat(heightPercent);
    return PixelRatio.roundToNearestPixel((screenHeight * elemHeight) / 100);
    ;
    export  widthPercentageToDP, heightPercentageToDP ;

heightPercentageToDP 的来源和来源: https://medium.com/react-native-training/build-responsive-react-native-views-for-any-device-and-support-orientation-change-1c8beba5bc23.

【讨论】:

【参考方案6】:

您可以使用一个可以维护每个设备的字体比例的小型库。

npm i --save react-native-responsive-fontsize

从“react-native-responsive-fontsize”导入 RF

字体大小:RF(2)

但不要忘记在文本中添加 allowFontScaling=false 属性。由于 ios 具有自动字体缩放功能,因此有时字体大小可能与您的预期不同。

【讨论】:

这似乎不会缩小文本以适应 元素。【参考方案7】:

快速回答使用Text属性adjustsFontSizeToFit

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案8】:

从 React Native 0.62 开始,Android 就支持文本组件的 adjustsFontSizeToFit 属性。检查docs。

【讨论】:

以上是关于如何在 React Native for Android 中调整字体大小以适应视图?的主要内容,如果未能解决你的问题,请参考以下文章

在React native 如何写if判断和for循环

如何在 React Native for android 中设置阴影?

如何在 React Native 中的循环中查找

如何在 react-native for android 中更改应用程序图标背景颜色

如何在“GraphQL for react-native”中链接模式(客户端和服务器)

我们如何在 React Native for iOS 中调整 RCTRootView 的大小/开始?