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

react

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

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

以上是 [RN] React Native 使用 FlatList 实现九宫格布局 GridList 的全部内容, 来源链接: utcz.com/z/384046.html

回到顶部