React-Native笔记--FlatList

龚迪
2023-12-01

          FlatList是ReactNative中一个常用控件,类似Android中的ListView,实质是基于<VirtulizedList>组件的封装。一个高性能的,用于渲染的列表组件,常见属性如下:

data - 数据源
renderItem - 列表呈现方式
extraData - 用于告诉列表重新渲染,因为它实现了PureComponent,但是props浅拷贝是不会重新渲染的
onEndReached - 下拉加载触发的函数
onEndReachedThreshold - 决定当距离内容最底部还有多远时触发onEndReached回调
onRefresh - 上拉刷新触发的函数
refreshing - 在等待加载新数据时将此属性设为true,列表就会显示出一个正在加载的符号

栗子1:

import React, {Component} from 'react';
import {
  FlatList,
  StyleSheet,
  Text,
  View,
  Image,
  Dimensions,
} from 'react-native';

var {height, width} = Dimensions.get('window');
export default class FlatListBasics extends Component<Props> {
  constructor(props) {
    super(props);
    let arr = new Array();
    for (let i = 0; i < 20; i++) {
      arr[i] = {key: i + '',title: '测试数据' + i,};
    }
    this.state = {
      data: arr,
    };
  }

  _renderItem = ({item}) => {
    return (
      <View style={styles.mainLine}>
       <Text style={styles.lineId}>{item.key}</Text>
       <Text style={styles.lineTitle}>{item.title}</Text>
      </View>
    );
  };
  render() {
    return (
      <View style={styles.container}>
        <FlatList data={this.state.data} renderItem={this._renderItem} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1, // 填充满整个屏幕
            alignItems: 'center',
            // backgroundColor: "red"
          },
  mainLine: {
     width:width - 20,
    backgroundColor: 'red',
    flexDirection: 'row',
          },
  lineId: {
     flex:1,
    fontSize: 30,
    backgroundColor: 'blue',
  },
  lineTitle: {
    flex:2 ,
    fontSize: 25,

    backgroundColor: 'yellow',
  },
});

栗子2:

import React from 'react';
import { StyleSheet, Text, View, FlatList, Dimensions } from 'react-native';
const data =[
    { key: 'A' }, { key: 'B' }, { key: 'C' }, { key: 'D' }, { key: 'E' }, { key: 'F' }, { key: 'G' }, { key: 'H' }, { key: 'I' }, { key: 'J' },
    { key: 'K' },
];

const formatData = (data, numColumns) => {
    const numberOfFullRows = Math.floor(data.length / numColumns);
    let numberOfElementsLastRow = data.length -(numberOfFullRows*numColumns);
    while(numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0){
        data.push({key: 'blank-${numberOfElementsLastRow}',empty:true})
        numberOfElementsLastRow++;
    }
    return data;
};

const numColumns = 4;
export default class GridPlay extends React.Component {
renderItem = ({item , index}) => {
    if(item.empty === true) {
        return <View style={[styles.item,styles.itemInvisible]} />
    }
    return (
        <View 
         style={styles.item}
        >
        <Text style={styles.itemText}>{item.key}</Text>
        </View>
    );
}

    render() {
        return (
            <FlatList
              data={ formatData(data, numColumns)}
              style={styles.container}
              renderItem={this.renderItem}
              numColumns={4}
            />
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        marginVertical: 20,
    },
    item: {
        backgroundColor: '#4D243D',
      alignItems: 'center',
      justifyContent: 'center',
      flex: 1,
      margin: 3,
      height:Dimensions.get('window').width / numColumns, 
    },
    itemInvisible: {
        backgroundColor: 'transparent',
      },
      itemText: {
        color: '#fff',
      },  
});

栗子3:

const numColumns = 2;
const formatData = (data: any, numColumns: any) => {
    const numberOfFullRows = Math.floor(data.length / numColumns);
    let numberOfElementsLastRow = data.length - numberOfFullRows * numColumns;
    while (numberOfElementsLastRow !== numColumns && numberOfElementsLastRow !== 0) {
        data.push({ key: `blank-${numberOfElementsLastRow}`, empty: true });
        numberOfElementsLastRow++;
    }
    return data;
};

export class MyComponent extends React.Component<{}, BadgeInfoState> {
    constructor(props: any) {
        super(props);
        this.state = {
            badgeData: [],
            showSpinner: false,
            badgeTitle: '',
            showBadgeDetailModal: false,
            itemBadge: ''
        };
    }

    async componentDidMount() {
        this.setState({ showSpinner: true });
        const resultBadges: any = await DataAccess.getBadges();
        const levels = JSON.stringify(resultBadges[0]);
        const levelsSub = JSON.parse(levels);
        const t = levelsSub.badges;
        this.setState({
            badgeData: t,
            badgeTitle: resultBadges[0].level
        });
    }

    formatImgs() {
        const ImgItems: any = [];
        console.log(' formatImgs ', this.state.badgeData.length);
        _.forEach(this.state.badgeData, (item: any) => {
            ImgItems.push(
                <View style={styles.itemContentContainer}>
                    <Image style={styles.itemImagDetail} source={showIntegralActions(item.badge_image_url)} />
                    <Text>{item.badgeTitle}</Text>
                </View>
            );
        });
        return ImgItems;
    }

    onClose = () => {
        console.log('BadgesComponent onClose');
        this.setState({ showBadgeDetailModal: false });
    };

    _onPress = (item: any) => {
        console.log('_onPress item= ', item);
        this.setState({
            showBadgeDetailModal: true,
            itemBadge: item
        });
    };

    renderItem = ({ item }) => {
        if (item.empty === true) {
            return <View style={[styles.itemStyle, styles.itemInvisible]} />;
        }
        return (
            <View style={styles.itemStyle}>
                <TouchableOpacity onPress={() => this._onPress(item)}>
                    <Image style={styles.itemImagDetail} source={showIntegralActions(item.badge_image_url)} />
                    <Text>{item.badgeTitle}</Text>
                </TouchableOpacity>
            </View>
        );
    };

    formatImgGrid() {
        console.log(' formatImgGrid ');
        return (
            <FlatList
                data={formatData(this.state.badgeData, numColumns)}
                style={styles.container}
                renderItem={this.renderItem}
                numColumns={2}
            />
        );
    }

    render() {
        return (
            <Content>
                <Header noShadow={true} style={styles.headerDetail}>
                    <Left>
                        <Button transparent={true}>
                            <Icon name='angle-left' type='FontAwesome' style={styles.colorBlackDetail} />
                        </Button>
                    </Left>
                    <Body>
                        <Title style={styles.textContentDetail}>Badges</Title>
                    </Body>
                </Header>
                <Text style={styles.badgeTitle}>{this.state.badgeTitle}</Text>
                <View style={styles.itemContainer}>{this.formatImgGrid()}</View>
                <Modal
                    animationType='slide'
                    transparent={false}
                    visible={this.state.showBadgeDetailModal}
                    onRequestClose={() => {}}>
                    <BadgesDetailComponent closeModal={this.onClose} itemBadge={this.state.itemBadge} />
                </Modal>
            </Content>
        );
    }
}

 

 类似资料: