zoukankan      html  css  js  c++  java
  • [RN] React Native 使用 FlatList 实现九宫格布局 GridList

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

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

  • 相关阅读:
    python pandas写入excel文件
    Ubuntu Teamviewer安装使用
    Ubuntu18.04 有线无法正常上网(请读完全文再进行操作)
    2019/4/5 python正则表达式的中文文档
    2019/4/3 Python今日收获
    2019/3/28 Python今日收获
    2019/3/15 Python今日收获
    2019/3/9 Python今日收获
    2019/2/26 Python今日收获
    2019/2/19 Python今日收获
  • 原文地址:https://www.cnblogs.com/wukong1688/p/10851764.html
Copyright © 2011-2022 走看看