简体   繁体   中英

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.

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)
  • I tried allowFontScaling (Not worked)
  • Removed fontsize (Not worked)
  • Removed flex and set static width and height to view (Not worked)
  • 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. And from the docs probably it's not available in 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:

示例输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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