如何在React-Native(JavaScript)中显示文本的More/Less

xfb7svmp  于 2022-11-17  发布在  React
关注(0)|答案(7)|浏览(271)

我正在开发React原生应用程序。在这方面,我们正在显示一些描述文本,它可能是行数。
因此,如果数据超过3行,我必须显示更多和更少,如果它是展开的。

<FlatList
          style={styles.faltList}
          showsVerticalScrollIndicator
          data={data}
          extraData={this.state}
          renderItem={({ item, index }) => (
            <View style={styles.flatListCell}>
                <Text style={styles.description}>{item.description}</Text>
              </View>
            </View>
          )
          }
          ItemSeparatorComponent={() => (
            <View style={{ height: 10}} />
          )}
        />

我已经找到了react-native-view-more-text库,但我想通过自定义代码实现它。
注意:我将在平面列表中显示该文本。
有什么建议吗?

bbuxkriu

bbuxkriu1#

看看我的解决方案,我没有使用文本行,我使用文本长度代替。

import React, {useState} from 'react';
import {Text, View, Image, TouchableOpacity, StyleSheet} from 'react-native';

const PostContent = () => {
  const postDescription =
    "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
  const [showMore, setShowMore] = useState(false);

  return (
    <View style={styles.postContentContainer}>
      {postDescription.length > 120 ? (
        showMore ? (
          <TouchableOpacity onPress={() => setShowMore(!showMore)}>
            <Text style={styles.postDescription}>{postDescription}</Text>
            <Text style={styles.seeMore}>Show less</Text>
          </TouchableOpacity>
        ) : (
          <TouchableOpacity onPress={() => setShowMore(!showMore)}>
            <Text style={styles.postDescription}>
              {`${postDescription.slice(0, 120)}... `}
            </Text>
            <Text style={styles.seeMore}>Show more</Text>
          </TouchableOpacity>
        )
      ) : (
        <Text style={styles.postDescription}>{postDescription}</Text>
      )}
    </View>
  );
};

export default PostContent;

const styles = StyleSheet.create({
  postContentContainer: {
    // borderWidth: 1,
    // borderColor: 'red',
    flexDirection: 'column',
  },

  postMedia: {
    //borderWidth: 1,
    //borderColor: 'red',
    width: '100%',
    height: 280,
    resizeMode: 'cover',
  },

  postDescription: {
    paddingTop: 15,
    paddingHorizontal: 15,
    color: colors.text.black,
    fontFamily: fonts.family.body,
    fontSize: fonts.fontSizes.button,
    fontWeight: fonts.fontWeights.thin,
  },

  seeMore: {
    paddingHorizontal: 15,
    color: colors.text.grey,
    fontStyle: 'italic',
    textDecorationLine: 'underline',
    fontFamily: fonts.family.body,
    fontSize: fonts.fontSizes.button,
    fontWeight: fonts.fontWeights.thin,
  },
});
jq6vz3qz

jq6vz3qz2#

import React from 'react';
import PropTypes from 'prop-types';
import AnchorText from '../AnchorText';

import { StyledContainer, RegularText } from './styles';

export default class Description extends React.Component {
      constructor(props) {
super(props);
this.state = {
  showMore: true,
};
}

 onClick = () => {
this.setState({
  showMore: false,
});
};

 render() {
const { description } = this.props;
const { showMore } = this.state;
if (!description) return null;

return (
  <StyledContainer FD={'column'}>
    {showMore ? (
      <RegularText MT={1}>
        {description.slice(0, 150)}{' '}
        {description.length > 150 && (
          <AnchorText onClick={this.onClick} label=" .. Read more" />
        )}{' '}
      </RegularText>
    ) : (
        <RegularText MT={1}>{description}</RegularText>
    )}
  </StyledContainer>
);
 }
} 

Description.propTypes = {
 description: PropTypes.string,
 };

查看此Widget

y3bcpkx1

y3bcpkx14#

我试着这样做,希望对你和其他人有帮助!

const postTextContent = (props) => {
const [textShown, setTextShown] = useState(false); //To show ur remaining Text
const [lengthMore,setLengthMore] = useState(false); //to show the "Read more & Less Line"
const toggleNumberOfLines = () => { //To toggle the show text or hide it
    setTextShown(!textShown);
}

const onTextLayout = useCallback(e =>{
    setLengthMore(e.nativeEvent.lines.length >=4); //to check the text is more than 4 lines or not
    // console.log(e.nativeEvent);
},[]);
    
  return (
      <View style={styles.mainContainer}>
          <Text
              onTextLayout={onTextLayout}
              numberOfLines={textShown ? undefined : 4}
              style={{ lineHeight: 21 }}>{Your Long Text}</Text>

              {
                  lengthMore ? <Text
                  onPress={toggleNumberOfLines}
                  style={{ lineHeight: 21, marginTop: 10 }}>{textShown ? 'Read less...' : 'Read more...'}</Text>
                  :null
              }
      </View>
  )
}
kx1ctssn

kx1ctssn5#

您可以简单地使用numberOfLines,它是一个<Text>属性:
用于在计算文本布局(包括换行)后使用省略号截断文本,以使总行数不超过此数字。
显然,还有一个足够的逻辑处理程序,用于在state中保存哪些文本被显示,哪些被截断。
让我们看一下我刚刚创建的一个示例:

state = {
    textShown: -1,
  };

  toggleNumberOfLines = index => {
    this.setState({
      textShown: this.state.textShown === index ? -1 : index,
    });
  };

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={[
            { key: 'a', description: longText },
            { key: 'b', description: longText },
            { key: 'c', description: longText },
          ]}
          renderItem={({ item, index }) => (
            <View style={styles.flatListCell}>
              <Text
                numberOfLines={this.state.textShown === index ? undefined : 3}
                style={styles.description}>
                {longText}
              </Text>
              <Text
                onPress={() => this.toggleNumberOfLines(index)}
                style={{ color: 'red' }}>
                {this.state.textShown === index ? 'read less...' : 'read more...'}
              </Text>
            </View>
          )}
        />
      </View>
    );
  }

这里我使用state保存FlatList中元素的索引,如果没有显示,则保存的值为-1。
你可以在this snack中尝试它的行为,(我希望)它能重现你的情况。如果这是你要找的,请告诉我。(嗨,Anilkumar,我们已经见过面了:)

fquxozlt

fquxozlt6#

第一个实现很接近,但问题是,当文本等于3行时,“阅读更多”按钮会显示,这是不应该的,因为没有更多的文本。我通过更新状态中的行数以及检查文本是否已显示来修复它。

const ReadMoreText = ({ readMoreStyle, text, textStyle }) => {
  const [showMoreButton, setShowMoreButton] = useState(false);
  const [textShown, setTextShown] = useState(false);
  const [numLines, setNumLines] = useState(undefined);

  const toggleTextShown = () => {
    setTextShown(!textShown);
  };

  useEffect(() => {
    setNumLines(textShown ? undefined : 3);
  }, [textShown]);

  const onTextLayout = useCallback(
    (e) => {
      if (e.nativeEvent.lines.length > 3 && !textShown) {
        setShowMoreButton(true);
        setNumLines(3);
      }
    },
    [textShown],
  );

  return (
    <>
      <Text onTextLayout={onTextLayout} numberOfLines={numLines} style={textStyle} ellipsizeMode="tail">
        {text}
      </Text>

      {showMoreButton ? (
        <Text onPress={toggleTextShown} style={readMoreStyle}>
          {textShown ? 'Read Less' : 'Read More'}
        </Text>
      ) : null}
    </>
  );
};
lstz6jyr

lstz6jyr7#

有点晚了,但我已经开发了一个非常优化的轻量级解决方案,我称之为react-native-more-or-less
下面是如何使用它的示例:

import { MoreOrLess } from "react-native-more-or-less";

// ...

export default function App() {
  return (
    <MoreOrLess numberOfLines={3} textComponent={CustomText}>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry.
      Lorem Ipsum has been the industry's standard dummy text ever since the
      1500s, when an unknown printer took a galley of type and scrambled it to
      make a type specimen book. It has survived not only five centuries, but
      also the leap into electronic typesetting, remaining essentially
      unchanged. It was popularised in the 1960s with the release of Letraset
      sheets containing Lorem Ipsum passages, and more recently with desktop
      publishing software like Aldus PageMaker including versions of Lorem
      Ipsum.
    </MoreOrLess>
  );
}

数据:https://bundlephobia.com/package/react-native-more-or-less@0.3.0

相关问题