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
转载请著名出处!谢谢~~