繁体   English   中英

如何在 React-Naitve (Javascript) 中显示更多/更少的文本

[英]How to show for text More/Less in React-Naitve (Javascript)

我正在开发 react-native 应用程序。 在那,我们展示了一些关于Text的描述,它可能是行数。

因此,如果数据的行数超过 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库,但我想通过自定义代码来实现它。

注意:我在 Flatlist 中显示该文本。

有什么建议么?

我尝试过这种方式,希望对您和其他人有所帮助!

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>
  )
}

您可以简单地使用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。

您可以在这种小吃中尝试它的行为,(我希望)重现您的情况。 让我知道这是否是您正在寻找的。 (嗨,Anilkumar,我们已经见过 :))

第一个实现很接近,但问题是当文本等于 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}
    </>
  );
};

看看我的解决方案,我没有使用文本行,而是使用了文本长度。

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,
  },
});

聚会有点晚了,但我已经为此开发了一个非常优化的轻量级解决方案。 我称之为反应原生或多或少

以下是如何使用它的示例:

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

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,
 };

看看这个小部件

检查此代码的输出

state = {
    textLenth: null,
    numberOfLines: 3,
}
handleSeeMore = () => {
    this.state.textLenth
    ? this.setState({numberOfLines: 0})
    : this.setState({numberOfLines: 3});
};

     <Text
     numberOfLines={this.state.numberOfLines}
     onPress={() => this.handleSeeMore()}
     ellipsizeMode="middle"
     onTextLayout={({nativeEvent: {lines}}) =>
     this.setState({textLenth: lines.length === 3})
     }>
         This Gig Take a glance at the showcase of our artistic work:
         Modern and Trendy Logo Artworkslkjfkljf ksnfksfnsf Mascot &
         Custom Logo efdfg Artworks:lk knnk 'Explore the
         ultimate Experience..!' To fulfill your designing needs, 
         Make us Graphically Yours...!! Why Team StrideInIt? We 
         believe in our
     {'                      '}
         {this.state.textLenth && (
         <Text
         color="red"
         onPress={() => this.setState({numberOfLines: 0})}>
             see more
         </Text>
         )}
     </Text>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM