当前位置 : 主页 > 网页制作 > React >

[RN] React Native 使用 FlatList 实现九宫格布局

来源:互联网 收集:自由互联 发布时间:2021-06-15
React Native 使用 FlatList 实现九宫格布局 先看图片演示实例: 本文以图片列表为例,实现九宫格布局! 主要有两种方法: 1)方法一: 利用FlatList的 numColumns ={ 2 } // 一行2个 2)方法二:

React Native 使用 FlatList 实现九宫格布局

先看图片演示实例:

 

 

本文以图片列表为例,实现九宫格布局!

主要有两种方法:

1)方法一:

利用FlatList的

numColumns ={2} // 一行2个

 

2)方法二:

利用 FlatList的

contentContainerStyle={styles.listViewStyle}

其中样式如下:

listViewStyle: {
// 主轴方向
flexDirection: ‘row‘,
// 一行显示不下,换一行
flexWrap: ‘wrap‘,
// 侧轴方向
alignItems: ‘center‘, // 必须设置,否则换行不起作用
},

 

当然,有一个重要的前提是,列表中的元素宽度 当然也要设置为宽度的 1/N,

 

看实际使用例子代码:

import React, {Component} from react;
import {FlatList, ActivityIndicator, Image, RefreshControl, Text, TouchableHighlight, View} from react-native;
import Dimensions from Dimensions;

import styles from ../../style/ImageStyle;
import ArrUtil from ../../util/ArrUtil;
import HttpRequest from ../../common/HttpRequest;

const baseUrl = https://raw.githubusercontent.com/wukong1688/RN-AppNews/master/apk/data/image_list_;

const screenWidth = Dimensions.get(window).width;

let pageNo = 0;//当前第几页
let totalPage = 2;//总的页数

/**
 * 新闻主页
 */
class ImagePage extends Component {
    constructor(props) {
        super(props);
        //在这里定义json返回的key
        this.state = {
            //下拉刷新,上拉加载
            isRefreshing: true, //下拉刷新标记
            isLoading: false,  //上拉加载标记

            //data数据
            resultJson: null,
            error_code: ‘‘,
            reason: ‘‘,
            data: {},

            //网络请求状态
            error: false,
            errorInfo: "",

            showFoot: 0, // 控制foot, 0:隐藏footer  1:已加载完成,没有更多数据   2 :显示加载中
        }
    }

    componentDidMount() {
        pageNo = 0; //切换tab时 pageNo 也要归零
        this.fetchData(baseUrl + 0.json, 0); //默认从0页数据开始读
    }

    fetchData(url, pageNo) {
        const opts = {
            method: GET,
            headers: HttpRequest.getHeaders(),
        };
        fetch(url, opts)
            .then((res) => {
                return res.json();
            })
            .then((response) => {
                this.setData(response);
            })
            .catch((error) => {
                alert(error);
                // console.error(error);
            })
            .done();
    }

    setData(response){
        let foot = 0;
        if (pageNo >= totalPage) {
            foot = 1;//listView底部显示没有更多数据了
        }

        let dataRes = [];
        let responseData = ArrUtil.shuffle(response.results);
        if (this.state.isRefreshing) {  //刷新,以前的数据全部清掉
            dataRes = responseData;
        } else {  //加载,数据追加到后面
            dataRes = this.state.data.concat(responseData);
        }

        this.setState({
            isRefreshing: false,
            isLoading: false,

            showFoot: foot,

            data: dataRes,
        });
    }

    //下拉刷新
    _onRefresh(type) {
        this.setState({
            showFoot: 2,
            isRefreshing: true
        });
        pageNo = 0; //刷新时,页码归0
        this.fetchData(baseUrl + type + .json, type);
    }

    //列表点击事件
    itemClick(item, index) {
        this.props.navigation.navigate(ImageDetail, {
            title: item.desc,
            url: item.url,
        })
    }

    //FlatList的key
    _keyExtractor = (item, index) => index.toString();

    //子item渲染
    _renderItem = ({item, index}) => {
        let w = screenWidth * 0.5 - 7;
        let h = screenWidth * 0.65 - 7;
        let style = styles.itemPadding;

        return (

            <TouchableHighlight
                key={item._id}
                style={style}
                underlayColor={rgba(255,255,255,0.5)}
                onPress={this.itemClick.bind(this, item, index)}
            >
                <Image
                    defaultSource={require(../../res/image_icon.png)}
                    source={{uri: item.url}} style={{height: h, width: w}}
                    resizeMethod="resize"
                />
            </TouchableHighlight>

        )
    };

    //列表分割线
    _itemDivide = () => {
        return (
            <View style={{height: 1}}/>
        )
    };

    _renderFooter() {
        if (this.state.showFoot === 1) {
            return HttpRequest.renderMoreDataEmptyView();
        } else if (this.state.showFoot === 2) {
            return HttpRequest.renderMoreDataLoadingView();
        } else if (this.state.showFoot === 0) {
            return HttpRequest.renderMoreDataNoneView();
        }
    }

    _onEndReached() {
        //如果是正在加载中或没有更多数据了,则返回
        if (this.state.showFoot != 0) {
            return;
        }

        //如果当前页大于或等于总页数,那就是到最后一页了,返回
        if ((pageNo != 1) && (pageNo >= totalPage)) {
            return;
        } else {
            pageNo++;
        }
        //底部显示正在加载更多数据
        this.setState({
            showFoot: 2,
            isLoading: true,
        });
        //获取数据
        this.fetchData(baseUrl + pageNo + .json, pageNo);
    }


    render() {
        //第一次加载等待的view
        if (this.state.isRefreshing && !this.state.error) {
            return HttpRequest.renderLoadingView();
        } else if (this.state.error) {
            //请求失败view
            return HttpRequest.renderErrorView(this.state.error);
        }
        //加载数据
        return this.renderData();
    }

    renderData() {
        return (

            <FlatList
                data={this.state.data}
                keyExtractor={this._keyExtractor}
                renderItem={this._renderItem}
                ItemSeparatorComponent={this._itemDivide}

                // 方法1)
                // numColumns ={2} // 一行2个

                // 方法2)
                contentContainerStyle={styles.listViewStyle}

                //下拉刷新
                refreshControl={
                    <RefreshControl
                        refreshing={this.state.isRefreshing}
                        onRefresh={this._onRefresh.bind(this, 0)}
                    />
                }

                //上拉加载
                ListFooterComponent={this._renderFooter.bind(this)}
                onEndReached={this._onEndReached.bind(this)}
                onEndReachedThreshold={1}
            />

        );
    }


}

module.exports = ImagePage;

 

样式:

listViewStyle: {
        // 主轴方向
        flexDirection: row,
        // 一行显示不下,换一行
        flexWrap: wrap,
        // 侧轴方向
        alignItems: center, // 必须设置,否则换行不起作用
    },

 

参考:

https://blog.csdn.net/a_zhon/article/details/78137936

 

本博客地址: wukong1688

本文原文地址:https://www.cnblogs.com/wukong1688/p/10851764.html

转载请著名出处!谢谢~~

网友评论