React native决定何时切断文本

时间:2016-05-01 01:44:56

标签: ios react-native textwrapping

我使用的是反应原生的有限数量的线条,显示为' ...'使用

<Text numberOfLines={4}> {myText} </Text>

现在我的问题是,如果文本被截断,我想展示一些特殊的图像,导航到一个新的视图。我想知道是否有一个属性我可以用来测试文本是否被切断?

4 个答案:

答案 0 :(得分:6)

现在还没有这个属性(不幸的是)。

这里有一个功能请求:https://github.com/facebook/react-native/issues/2496(还有一些关于如何使其正常工作的建议,但实施链接已关闭)。

你可以测量一定数量的线占用的空间,然后自己处理吗?但不理想。

答案 1 :(得分:2)

我在这里回答了一个相关问题-https://stackoverflow.com/a/60500348/5449850

到目前为止,几乎所有我从事过的React Native应用程序都要求这样做。我终于有了解决方案,并且已经开源了。

https://github.com/kashishgrover/react-native-see-more-inline

https://www.npmjs.com/package/react-native-see-more-inline

正如我在回购中所述,

建立此代码的动机是,我找不到任何可将“查看更多”链接与文本内联的库/实现。我发现的所有其他其他实现方式会将链接放在文本下方。 此程序包使用文本宽度,并使用简单的二进制搜索(几乎)准确地计算出应在何处放置“查看更多”链接。

我不确定这是否是最有效的解决方案,但可以解决我的用例。当我找到更好的解决方案时,我将更新答案。

这就是我所做的:

findTruncationIndex = async (containerWidth) => {
  if (
    this.containerWidthToTruncationIndexMap
    && this.containerWidthToTruncationIndexMap[containerWidth]
  ) {
    this.setState({ truncationIndex: this.containerWidthToTruncationIndexMap[containerWidth] });
    return;
  }

  const {
    children: text,
    style: { fontSize, fontFamily, fontWeight },
    seeMoreText,
    numberOfLines,
  } = this.props;

  const { width: textWidth } = await reactNativeTextSize.measure({
    text,
    fontSize,
    fontFamily,
    fontWeight,
  });

  const textWidthLimit = containerWidth * numberOfLines;

  if (textWidth < textWidthLimit) {
    this.setState({ truncationIndex: undefined });
    return;
  }

  const { width: seeMoreTextWidth } = await reactNativeTextSize.measure({
    text: ` ...${seeMoreText}`,
    fontSize,
    fontFamily,
    fontWeight,
  });

  const truncatedWidth = textWidthLimit - 2 * seeMoreTextWidth;

  let index = 0;
  let start = 0;
  let end = text.length - 1;

  while (start <= end) {
    const middle = start + (end - start) / 2;
    // eslint-disable-next-line no-await-in-loop
    const { width: partialWidth } = await reactNativeTextSize.measure({
      text: text.slice(0, middle),
      fontSize,
      fontFamily,
      fontWeight,
    });
    if (Math.abs(truncatedWidth - partialWidth) <= 10) {
      index = middle;
      break;
    } else if (partialWidth > truncatedWidth) {
      end = middle - 1;
    } else {
      start = middle + 1;
    }
  }

  const truncationIndex = Math.floor(index);

  // Map truncation index to width so that we don't calculate it again
  this.containerWidthToTruncationIndexMap = {
    ...this.containerWidthToTruncationIndexMap,
    [containerWidth]: truncationIndex,
  };
  this.setState({ truncationIndex });
};

您可以在我上面共享的GitHub链接中看到此组件的完整实现。

答案 2 :(得分:1)

Text组件有一个onPress事件,可以处理该事件以导航到另一个场景。要启用导航,应将具有文本的组件放在NavigationIOS组件中。 Text组件也有ellipsizeMode属性,它在尾部放置“...”。

<Text 
  numberOfLines={4}
  ellipsizeMode="tail"
  onPress={(e) => this.props.navigator.push({component: Detail})}
>
  {myText}
</Text>

答案 3 :(得分:0)

react-native-read-more-text模块为该问题提供了现成的解决方案:

ResultSet rs = ...
List<Pair<String, String>> list = new ArrayList<>();
while (rs.next()) {
    list.add(new Pair(rs.getString("column1"), rs.getString("column2")));
}