背景:
开发遇到的问题 发现网上没有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,
},
});
实现效果
类似淘宝这种,区别是代码中有收起功能