FlatList可以利用官方組件
不過我們仍可以通過
RefreshControl
實現下拉刷新功能,但官方沒有提供相應的上拉加載的組件,因此在RN中實現上拉加載比下拉刷新要復雜一點。
不過我們仍可以通過
FlatList
的
onEndReached
與
onEndReachedThreshold
屬性來實現相應效果。
我們以
github
提供的
api為例
先查看效果:

具體實現代碼如下:
import React, {Component} from "react"; import {ActivityIndicator, FlatList, StyleSheet, Text, View, Image} from "react-native"; const REQUEST_URL = 'https://api.github.com/search/repositories?q=javascript&sort=stars&page='; let pageNo = 1;//當前第幾頁 let totalPage=5;//總的頁數 let itemNo=0;//item的個數 class Home extends Component { constructor(props) { super(props); this.state = { isLoading: true, //網絡請求狀態 error: false, errorInfo: "", dataArray: [], showFoot:0, // 控制foot, 0:隱藏footer 1:已加載完成,沒有更多數據 2 :顯示加載中 isRefreshing:false,//下拉控制 } } //網絡請求——獲取第pageNo頁數據 fetchData(pageNo) { //這個是js的訪問網絡的方法 fetch(REQUEST_URL+pageNo) .then((response) => response.json()) .then((responseData) => { let data = responseData.items; let dataBlob = []; let i = itemNo; data.map(function (item) { dataBlob.push({ key: i, value: item, }) i++; }); itemNo = i; console.log("itemNo:"+itemNo); let foot = 0; if(pageNo>=totalPage){ foot = 1;//listView底部顯示沒有更多數據了 } this.setState({ //復制數據源 dataArray:this.state.dataArray.concat(dataBlob), isLoading: false, showFoot:foot, isRefreshing:false, }); data = null; dataBlob = null; }) .catch((error) => { this.setState({ error: true, errorInfo: error }) }) .done(); } componentDidMount() { //請求數據 this.fetchData( pageNo ); } //加載等待頁 renderLoadingView() { return ( <View style={styles.container}> <ActivityIndicator animating={true} color='red' size="large" /> </View> ); } //加載失敗view renderErrorView() { return ( <View style={styles.container}> <Text> Fail </Text> </View> ); } //返回itemView _renderItemView({item}) { return ( <View style={styles.itemBox}> <View style={styles.leftArea}> <Image style={styles.avatar} source={{uri:item.value.owner.avatar_url}} /> </View> <View style={styles.rightArea}> <Text style={styles.title}>{item.value.name}</Text> <Text style={styles.desc}>{item.value.description}</Text> </View> </View> ); } renderData() { return ( <FlatList data={this.state.dataArray} renderItem={this._renderItemView} ListFooterComponent={this._renderFooter.bind(this)} onEndReached={this._onEndReached.bind(this)} onEndReachedThreshold={1} ItemSeparatorComponent={this._separator} /> ); } render() { //第一次加載等待的view if (this.state.isLoading && !this.state.error) { return this.renderLoadingView(); } else if (this.state.error) { //請求失敗view console.log(this.state.error); console.log(this.state.errorInfo); return this.renderErrorView(); } //加載數據 return this.renderData(); } _separator(){ return <View style={{height:1,backgroundColor:'#999999'}}/>; } _renderFooter(){ if (this.state.showFoot === 1) { return ( <View style={{height:30,alignItems:'center',justifyContent:'flex-start',}}> <Text style={{color:'#999999',fontSize:14,marginTop:5,marginBottom:5,}}> 沒有更多數據了 </Text> </View> ); } else if(this.state.showFoot === 2) { return ( <View style={styles.footer}> <ActivityIndicator /> <Text>正在加載...</Text> </View> ); } else if(this.state.showFoot === 0){ return ( <View style={styles.footer}> <Text></Text> </View> ); } } _onEndReached(){ //如果是正在加載中或沒有更多數據了,則返回 if(this.state.showFoot != 0 ){ return ; } //如果當前頁大於或等於總頁數,那就是到最后一頁了,返回 if((pageNo!=1) && (pageNo>=totalPage)){ return; } else { pageNo++; } //底部顯示正在加載更多數據 this.setState({showFoot:2}); //獲取數據 this.fetchData( pageNo ); } } const styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, itemBox: { flex:1, flexDirection:'row', paddingTop:8, paddingBottom:8, paddingLeft:6, paddingRight:6, }, leftArea: { flex:1, justifyContent: 'center', alignItems: 'center', }, avatar: { width:40, height:40, }, rightArea: { flex:5, justifyContent: 'center', alignItems: 'center', }, title: { fontSize: 15, color: 'blue', }, desc: { fontSize: 15, color: 'black', }, }); module.exports = Home;