react-native自定义文本省略号,以在省略号后添加“更多”

时间:2020-10-15 06:41:23

标签: react-native

关注来自instagram,它以使用react-native闻名

如您所见,省略号(...)后有一个文本(더보기,表示More
我该如何模拟呢?

enter image description here

2 个答案:

答案 0 :(得分:0)

这是一个快速的解决方法。创建一个函数,该函数将文本作为参数,并使用more按钮显示截断的文本。单击后,我们将使用较少的按钮呈现全文。

const MoreLessComponent = ({ truncatedText, fullText }) => {
  const [more, setMore] = React.useState(false);
  return (
    <Text>
      {!more ? `${truncatedText}...` : fullText}
      <TouchableOpacity onPress={() => setMore(!more)}>
        <Text>{more ? 'less' : 'more'}</Text>
      </TouchableOpacity>
    </Text>
  );
};

const MoreInfo = (text, linesToTruncate) => {
  const [clippedText, setClippedText] = React.useState(false);
  return clippedText ? (
    <MoreLessComponent truncatedText={clippedText} fullText={text} />
  ) : (
    <Text
      numberOfLines={linesToTruncate}
      ellipsizeMode={'tail'}
      onTextLayout={(event) => {
        //get all lines
        const { lines } = event.nativeEvent;
        //get lines after it truncate
        let text = lines
          .splice(0, linesToTruncate)
          .map((line) => line.text)
          .join('');
        //substring with some random digit, this might need more work here based on the font size
        //
        setClippedText(text.substr(0, text.length - 9));
      }}>
      {text}
    </Text>
  );
};


现在这样称呼

<View>
        {MoreInfo('Change code in the editor and watch it change on your phone! Save to get a shareable url.')}
      </View>

这是小吃https://snack.expo.io/@saachitech/react-native-more-less

答案 1 :(得分:0)

好吧,这是表面上看起来很容易的事情之一,但实际上是一项复杂的工作。

由于此处的原因:https://github.com/facebook/react-native/issues/22811您将无法嵌套<Text>标签并使用numberOfLines道具来实现所需的内容。

过去,我曾尝试处理类似的问题:React Native chat bubble flexbox similar to whatsapp

那时没有onTextLayout函数(或者至少我不知道)。 Text组件上的onTextLayout回调为您提供了线路道具。该行是一个数组,其中包含有关每一行文本的信息。 您可以使用此按钮将更多按钮放置在所需位置。

const MoreInfo = text => {
  const [moreLeft, setMoreLeft] = React.useState(0)
  const [moreTop, setMoreTop] = React.useState(0)
  return (
    <View style={{ marginTop: 20 }}>
      <Text
        numberOfLines={2}
        ellipsizeMode={"tail"}
        onTextLayout={({ nativeEvent: { lines } }) => {
          const width = lines[lines.length - 1].width
          const height = lines[lines.length - 1].y

          setMoreTop(height)
          setMoreLeft(width)
        }}
      >
        {text}
      </Text>
      <Text
        style={{
          backgroundColor: "white",
          position: "absolute",
          left: moreLeft - 30,
          top: moreTop,
        }}
      >
        ... More
      </Text>
    </View>
  )
}

显然,以上实现并不完美。如您所见,我只是通过将它们放在“更多”按钮中来伪造...。有时看起来不错,有时它会切断字符串中间的最后一个字母。但这可以显示您解决该问题所需的方向。

一些想法: 检查lines数组-如果它有2条线的最后一条线宽小于第一条线宽。您的“更多”文本是否适合宽度差异?如果是,则将左侧位置设置为宽度。 如果第二行与第一行一样长,那么省略号就在最后,您需要诉诸“ ...更多”技巧。