React Native:确定Text组件的行数

col*_*fet 15 android text ios react-native

正如标题所说,我一直试图找到一种方法来确定文本组件在给出文本之后的行数.看看下面的例子.

<Text>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi semper ut ipsum in ultrices. Vivamus fringilla lacinia odio in accumsan. Proin sit amet pellentesque tortor. Nam mollis sit amet ligula id convallis. Etiam in semper diam. Cras id elit consectetur, interdum ante id, tincidunt nisi. Integer non elit placerat, dignissim nibh at, faucibus sem. Curabitur nec posuere turpis. Vivamus rhoncus nulla vitae mi imperdiet, elementum eleifend mi laoreet. Vestibulum molestie turpis non nibh elementum, sed ornare magna tristique. Aliquam erat volutpat. Phasellus volutpat mi vel tempor finibus.
</Text>
Run Code Online (Sandbox Code Playgroud)

在运行时,如何确定此Text组件已呈现的行数.此数字将根据设备而有所不同(例如,iPhone 5将需要渲染更多的线与iPhone 6+,因为它具有更小的屏幕尺寸).我已经检查了Text组件的源代码,但似乎没有我想要的东西.

我正在使用React Native 0.24.

有任何想法吗?

干杯.

Arn*_*rno 37

我想提供一个现代的解决方案。现在有一个onTextLayout事件,其中包含一个数组,lines可以确定正在渲染的行数。lines数组中还有其他详细信息,例如每行的实际高度和宽度,可进一步用于确定文本是否被截断。

const NUM_OF_LINES = 5;
const SOME_LONG_TEXT_BLOCK = 'Lorem ipsum ...';

function SomeComponent () { 
  const [ showMore, setShowMore ] = useState(false);
  const onTextLayout = useCallback(e => {
    setShowMore(e.nativeEvent.lines.length > NUM_OF_LINES);
  }, []);

  return (
    <Text numberOfLines={NUM_OF_LINES} onTextLayout={onTextLayout}>
      {SOME_LONG_TEXT_BLOCK}
    </Text>
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 这是行不通的。`e.nativeEvent.lines.length` 总是返回 `NUM_OF_LINES ` (4认同)

小智 9

这个适用于 IOS 和 Android

    const [ loadMore, setLoadMore ] = useState(false);
    const [ numOfLines, setNumOfLines ] = useState(0);

    const onTextLayout = useCallback(e => {
        if(numOfLines == 0)
            setNumOfLines(e.nativeEvent.lines.length);
    });

    const onLoadMoreToggle = () => {
        setLoadMore(!loadMore);
    }
    
    return (
        <View style={styles.container}>
            <Text 
                numberOfLines={numOfLines == 0 ? null : loadMore ? numOfLines : NUM_OF_LINES} 
                onTextLayout={onTextLayout} 
                style={styles.bodyText}
            >
                {props.children}
            </Text>
            {
                (numOfLines > NUM_OF_LINES) &&
                <View style={styles.linkContainer}>
                    <TouchableRipple onPress={onLoadMoreToggle}>
                        <Text style={styles.linkText}>{ loadMore? 'Load Less' :'Load More'}</Text>
                    </TouchableRipple>
                </View>
            }
        </View>
    )

const styles = StyleSheet.create({
    container: {
        display: 'flex',
        flexDirection:'column',
    },
    bodyText: {
        flex:1,
    },
    linkContainer: {
        flexDirection: 'row',
        justifyContent: 'flex-end'
    },  
    linkText: {
        color: '#2196f3'
    }
})
Run Code Online (Sandbox Code Playgroud)


小智 5

看起来React Native 0.24实现了onLayout函数
http://facebook.github.io/react-native/docs/text.html#onlayout

onLayout函数
使用
{nativeEvent:{layout:{x,y,width,height}}} 在安装和布局更改上调用

所以看起来你可以传递onLayout回调函数,获取Text组件的高度然后使用行高进行一些计算以得到行数

  • 分享工作的代码会很好 (2认同)