RN對列表已經實現了下拉刷新與上拉加載的功能,但是爲了更好用,做了封裝。
實現的功能:
1、下拉刷新,使用原生下拉頭。
2、上拉加載,自定義加載佈局。
3、處理了重複刷新或重複加載,或刷新時加載、加載時刷新的問題。
4、同時也可以添加底部佈局。
5、是否顯示空白布局。
FlatList的封裝
/**
* noEmptyRemind 是否不顯示空列表提醒boolean
* refreshAble 是否可以下拉刷新boolean
* refreshing 是否正在刷新boolean
* showFoot 項目列表上拉加載狀態int。1顯示空view/2正在加載中/3沒有更多數據了
* onRefresh 下拉刷新時觸發的方法function。
* onEndReached 上拉刷新時觸發的方法function。
*/
import React, {Component} from 'react';
import {
Text,
View,
FlatList,
ActivityIndicator,
ScrollView,
Image
} from 'react-native';
export default class CommonFlatList extends Component {
onRefresh = () => {
if (this.props.onRefresh) {
if (!this.props.refreshing && (!this.props.showFoot || this.props.showFoot !== 1)) {
this.props.onRefresh()
}
}
};
onEndReached = () => {
if (this.props.onEndReached) {
if (!this.props.refreshing && (!this.props.showFoot || (this.props.showFoot !== 1 && this.props.showFoot !== 2))) {
this.props.onEndReached()
}
}
};
renderFooter = () => {
switch (this.props.showFoot) {
case 0 : {
return null;
}
case 1 : {
return (
<View style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
height: 60
}}>
<ActivityIndicator/>
<Text style={{color: '#999999', fontSize: 14}}>
正在加載更多數據...
</Text>
</View>
)
}
case 2 : {
return (
<View style={{height: 60, alignItems: 'center', justifyContent: 'center',}}>
<Text style={{color: '#999999', fontSize: 14,}}>
沒有更多數據了
</Text>
</View>
);
}
default :
return null;
}
};
ListEmptyComponent = () => {
return (
<ScrollView
contentContainerStyle={{justifyContent: 'center', alignItems: 'center'}}
>
<Image
source={emptyImg}
style={{width: 123, height: 84, marginTop: 50}}
/>
<Text style={{color: '#9c9c9c'}}>{'暫無數據'}</Text>
</ScrollView>
)
};
ListFooterComponent = () => {
return (
<View>
{this.props.ListFooterComponent}
{this.renderFooter()}
</View>
)
};
render() {
return (
<FlatList
{...this.props}
data={this.props.data}
onEndReachedThreshold={0.2}
onEndReached={this.onEndReached}
refreshing={this.props.refreshing}
onRefresh={this.props.refreshAble && this.onRefresh}
ListEmptyComponent={!this.props.noEmptyRemind && this.ListEmptyComponent}
ListFooterComponent={this.ListFooterComponent}
ref={ref => this.flatList = ref}
/>
);
}
}
例子
let pageSize = 20;
export default class Demo extends Component {
constructor(props) {
super(props);
this.state = {
dataList: [],
refreshing: false,
showFoot: 0
}
}
componentDidMount() {
this.getData(true);
};
getData = async (isRefresh) => {
let pageStart = isRefresh ? 0 : this.props.listData.length;
if (isRefresh) {
this.setState({refreshing: true, showFoot: 0});
} else {
this.setState({refreshing: false, showFoot: 1});
}
fetch(requestUrl, requestParam).then((response) => {
return response.json();
}).then((reslut) => {
let showFoot = this.state.refreshing && result.length < pageSize ? 2 : 0;
if (result && reslut.length > 0) {
this.setState({
dataList: this.state.refreshing ? [...result] : this.state.dataLIst.concat(result),
refreshing: false,
showFoot: showFoot
});
} else {
this.setState({
refreshing: false,
showFoot: this.state.refreshing ? 0 : 2
});
}
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
this.setState({
refreshing: false,
showFoot: 0
})
});
};
renderItem({item}) {
return (
<View>
<Text>item</Text>
</View>
);
}
onRefresh= () => {
this.getData(true)
};
onEndReached = () => {
this.getData(false);
};
keyExtractor = ({item, index}) => {
return index;
};
render() {
return (
<View style={styles.listBoxStyle}>
<YYFlatList
data={this.props.listData}
keyExtractor={(item) => this.keyExtractor(item)}
renderItem={ this.renderItem}
refreshAble={true}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh}
showFoot={this.state.showFoot}
onEndReached={this.onEndReached}
/>
</View>
)
}
}
const styles = StyleSheet.create({
listBoxStyle: {
// flex: 1,
paddingTop: 10,
backgroundColor: "#F3F3F3"
}
});