实现超过两行或多行显示展开收起(RN)

2,230 阅读1分钟

背景:

开发遇到的问题 发现网上没有RN 相关的回答,记录一下

功能:

要求一个数组循环生成 tag,超过两行的时候有展开收起功能

具体实现:

import React, { Component } from 'react';

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

import PropTypes from 'prop-types';



export default class TagList extends Component {

  static propTypes = {

    data: PropTypes.array, // item数据

  };



  static defaultProps = {

    data: [],

  };



  constructor(props) {

    super(props);

    this.state = {

      iconShow: false, // 是否需要展开收起(内容是否超过所需行数)

      isOpen: false, // 展开收起开关

      sliceIndex: 0, // 截断索引

    };

    this.lineNum = 0; // 数据行数

  }



// 操作展开收起

  openList = () => {

    const { isOpen } = this.state;

    this.setState({

      isOpen: !isOpen,

    });

  };





  _onLayout = (e, index) => {

    let { x } = e.nativeEvent.layout;

    if (x === 0) {

      if (this.lineNum === 2) { // 超过两行收起 2可替换为 n

        this.setState({

          iconShow: true, // 超过两行需要展开收起功能

          sliceIndex: index - 1, // 将第n行最后一个元素替换成展开收起按钮

        });

      }

      this.lineNum++; // 存储行数

    }

  };

  render() {

    const { data } = this.props;

    const { isOpen, iconShow, sliceIndex } = this.state;

    return (

      <View style={styles.container}>

        {(!iconShow || isOpen ? data : data.slice(0, sliceIndex)).map((item, index) => {

          return (

            <Text onLayout={(e) => this._onLayout(e, index)} style={styles.tag} key={index}>

              {item}

            </Text>

          );

        })}

        {iconShow && (

          <TouchableOpacity onPress={this.openList}>

            <Image

              style={{ width: 22, height: 22 }}

              source={isOpen ? '收起图标路径' : '展开图标路径'}

            />

          </TouchableOpacity>

        )}

      </View>

    );

  }

}

const styles = StyleSheet.create({

  container: {

    flexDirection: 'row',

    flexWrap: 'wrap',

  },

  tag: {

    color: '#333333',

    fontSize: 10,

    backgroundColor: '#F5F6FA',

    paddingHorizontal: 10,

    paddingVertical: 5,

    marginRight: 10,

    marginBottom: 10,

    borderRadius: 3,

  },

});

实现效果

类似淘宝这种,区别是代码中有收起功能

image.png

image.png