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
轉載請著名出處!謝謝~~