React Native中如何截断文本末行并追加内容?
解决React Native文本截断后追加「更多/收起」避免覆盖的问题
实现思路
直接用numberOfLines无法控制末尾追加的「更多」不覆盖原有文本,需要通过以下逻辑实现需求:
- 先判断文本是否会超出指定行数(比如2行)
- 若超出,截断文本并在末尾追加
... 更多;未超出则直接显示原文本 - 通过状态控制展开/收起状态,展开时显示完整文本,收起时显示截断后的文本
具体代码实现
1. 自定义可展开文本组件
import React, { useState, useRef, useEffect } from 'react'; import { Text, TouchableOpacity } from 'react-native'; const ExpandableText = ({ text, maxLines = 2 }) => { const [isExpanded, setIsExpanded] = useState(false); const [isTextOverflow, setIsTextOverflow] = useState(false); const textRef = useRef(null); useEffect(() => { // 检测文本是否超出指定行数 const checkOverflow = () => { if (!textRef.current) return; const { layoutHeight, lineHeight } = textRef.current; const actualLines = Math.floor(layoutHeight / lineHeight); setIsTextOverflow(actualLines > maxLines); }; checkOverflow(); }, [text, maxLines]); // 生成截断后带「更多」的文本 const getTruncatedText = () => { if (!isTextOverflow) return text; // 预留「...更多」的字符位置,粗略计算每行字符数(可根据实际行高调整) const charsPerLine = 30; const allowedChars = charsPerLine * maxLines - 6; return `${text.slice(0, allowedChars)}... 更多`; }; const showText = isExpanded ? text : getTruncatedText(); return ( <TouchableOpacity onPress={() => setIsExpanded(!isExpanded)} activeOpacity={0.8} > <Text ref={textRef} numberOfLines={isExpanded ? undefined : maxLines} style={{ lineHeight: 22 }} // 固定行高方便行数计算 > {showText} {isExpanded && isTextOverflow ? ' 收起' : ''} </Text> </TouchableOpacity> ); }; export default ExpandableText;
2. 组件使用示例
import ExpandableText from './ExpandableText'; // 在业务组件中调用 <ExpandableText text="Hello, This is React Native. I want to format this." maxLines={2} />
优化提示
- 上面的截断逻辑是粗略计算,若需要更精准的截断,可以通过
onTextLayout获取每行的具体字符数后再计算截断位置 - 如果不想自定义逻辑,也可以直接使用成熟的第三方库(如
react-native-read-more-text)实现相同效果
内容的提问来源于stack exchange,提问作者Anvesh Chekati
相关产品推荐
相关产品推荐

