简体   繁体   English

React Native 适配文本组件

[英]React Native fit Text Component

I'm trying to fit my text inside available area and my constraints are something like this:我试图将我的文本放在可用区域内,我的约束是这样的:

  • Text should not overflow,文字不应溢出,
  • Text must scales up inside all available view,文本必须在所有可用视图内按比例放大,
  • Words should not broken into characters and goes to next line sentences can be,单词不要分解成字符并转到下一行句子可以,
  • When I'm using flex inside parent view text should not expand view more than screen width horizontally.当我在父视图中使用 flex 时,文本不应水平扩展视图超过屏幕宽度。

Here is my code snippet:这是我的代码片段:

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { Font } from "expo";
import Lorem from "./src/helpers/lorem-ipsum-gen";

export default class App extends React.Component {
  constructor() {
    super()
    this.state = {
      fontLoaded: false,
    };
  }
  //theboldfont.ttf
  async componentWillMount() {
    await Font.loadAsync({
      "akzidenz-grotesk-bq-bold": require("./assets/fonts/AkzidenzGrotesk_BQ_Bold.otf"),
    });
    this.setState({ fontLoaded: true });
  }

  render() {
    let loremText = new Lorem().generate(20)

    return (
      <View style={styles.container}>
        <View>
          <View style={{ flex: 0.37 }} > </View>
          <View style={{ flex: 0.25, backgroundColor: "red" }} >
            <View >
              {
                this.state.fontLoaded ? (<Text
                  style={{ fontFamily: "akzidenz-grotesk-bq-bold", fontSize: 50 }}
                  adjustsFontSizeToFit={true}
                >
                  {loremText}
                </Text>) : null
              }

            </View>
          </View>
          <View style={{ flex: 0.38 }} >
            <Text>
              {loremText}
            </Text>
          </View>
        </View>
      </View>
    );
  }
}

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

And result of it:以及它的结果:

示例截图

What I've tried to achieve my goal:我试图实现我的目标:

  • I thought it's related with custom font & changed to default font(Not worked)我认为它与自定义字体有关并更改为默认字体(无效)
  • In some github issues people wrote adjustsFontSizeToFit={true} inside text style prop (Not worked)在一些 github 问题中,人们在 text style prop 中写了 adjustsFontSizeToFit={true} (无效)
  • I tried allowFontScaling (Not worked)我试过 allowFontScaling(无效)
  • Removed fontsize (Not worked)删除了字体大小(不起作用)
  • Removed flex and set static width and height to view (Not worked)删除了 flex 并设置静态宽度和高度以查看(无效)
  • Combinations of all steps above (Not worked)以上所有步骤的组合(无效)

So after trying new things on text component I've found that adjustsFontSizeToFit={true} is not working without specifying numberOfLines={number} however it is dividing my words into characters sometimes at the end of the line.因此,在对文本组件尝试新事物后,我发现adjustsFontSizeToFit={true}在没有指定numberOfLines={number}情况下不起作用,但是它有时会在行尾将我的单词分成字符。 And from the docs probably it's not available in android.从文档来看,它可能在 android 中不可用。 So I still need a better way to find a solution to my problem所以我仍然需要更好的方法来解决我的问题

Note : this solution takes trial and error and assumes a container of fixed size.注意:此解决方案需要反复试验并假定容器大小固定。

You can use an interpolation function to scale down text based on the length of the longest line.您可以使用插值函数根据最长行的长度缩小文本。

Interpolation function example (Feel free to take my interpolation function ):插值函数示例(随意使用我的插值函数):

const fontSizeInterpolator = Interpolator.getInterpolator({
    input:  [4,  5,  6,  7,  8,  10, 11, 13, 40],
    output: [45, 45, 32, 28, 28, 22, 19, 15, 10]
});

This means if the longest line is four characters long, set the font size very large.这意味着如果最长的一行是四个字符长,请将字体设置得非常大。 If the longest line is forty characters long, set the font size very small.如果最长的一行是四十个字符,请将字体设置得非常小。 From trial and error, specific line lengths are mapped to specific font sizes.通过反复试验,特定的行长被映射到特定的字体大小。

Find the longest line in the text via normal logic (here I only have one word per line):通过正常逻辑找到文本中最长的一行(这里我每行只有一个单词):

const words = props.text.split(' ');
let longestWord = words[0];
for (const word of words) {
  if (word.length > longestWord.length) {
    longestWord = word;
  }
}

Then get the font size from your interpolator:然后从插值器获取字体大小:

const fontSize = fontSizeInterpolator(longestWord.length);

Example output:示例输出:

示例输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM