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"
}
});