完成拉下拉刷新的功能后,老板要求下拉刷新要能自定义。于是到网上找了找,发现了react-native-pull这个开源库。但是这个库本身已经很久没更新,里面使用的还是被淘汰的listView,于是我到源码看了看,把列表替换成了flatList,顺便修复了几个bug。
react-native-flatlist-pull是一个基于FlatList,支持Android和iOS的下拉刷新列表组件。是在另一个项目react-native-pull的基础上进行修改而成。主要将原项目中已经过时的ListView替换成较新的FlatList,同时去掉了原项目中存在BUG的PullView。
PullList
使用npm install react-native-flatlist-pull@latest --save
yarn add react-native-flatlist-pull
import {PullList} from 'react-native-pull';
onPullRelease(resolve) {
//do something
setTimeout(() => {
resolve();
}, 3000);
}
<PullList
onPullRelease={this.onPullRelease}
// topIndicatorRender={this.topIndicatorRender}
topIndicatorHeight={60}
isRefreshing={this.state.isRefreshing}
{...and some FlatList Props}
/>
PullList 下拉效果属性
style
: 设置组件样式,比如可以设置width/height/backgroudColor等onPulling
: 处于pulling
状态时执行的方法onPullOk
: 处于onPullOk
状态时执行的方法onPullRelease
: 处于pullrelease
状态时执行的方法topIndicatorRender
: 顶部刷新指示组件的渲染方法, 接受4个参数: ispulling
, ispullok
, ispullrelease
,gesturePosition
,你可以使用gesturePosition
定义动画头部.topIndicatorHeight
: 顶部刷新指示组件的高度, 若定义了topIndicatorRender
则同时需要此属性isPullEnd
: 是否已经下拉结束,若为true则隐藏顶部刷新指示组件,非必须isRefreshing
: 标示下拉刷新状态的属性,同react-native官网FlatList中的属性refreshing作用类似。为true显示头部刷新指示器,为false则隐藏头部刷新指示器PullList 上拉加载更多,可直接使用官网FlatList的属性onEndReached与onEndReachedThreshold进行实现,详情请见Example
import React, { Component } from 'react';
import {
Text,
View,
ActivityIndicator,
} from 'react-native';
import {PullList} from 'react-native-flatlist-pull';
export default class extends Component {
constructor(props) {
super(props);
this.state = {
data: [0],
isRefreshing:false,
isLoadMore:false
};
this.loadMore = this.loadMore.bind(this);
this.topIndicatorRender = this.topIndicatorRender.bind(this);
this.onPullRelease=this.onPullRelease.bind(this);
}
componentDidMount() {
this.requestData(10);
}
//自定义下拉刷新指示器
topIndicatorRender(pulling, pullok, pullrelease) {
const hide = {position: 'absolute', left: 10000};
const show = {position: 'relative', left: 0};
setTimeout(() => {
if (pulling) {
this.txtPulling && this.txtPulling.setNativeProps({style: show});
this.txtPullok && this.txtPullok.setNativeProps({style: hide});
this.txtPullrelease && this.txtPullrelease.setNativeProps({style: hide});
} else if (pullok) {
this.txtPulling && this.txtPulling.setNativeProps({style: hide});
this.txtPullok && this.txtPullok.setNativeProps({style: show});
this.txtPullrelease && this.txtPullrelease.setNativeProps({style: hide});
} else if (pullrelease) {
this.txtPulling && this.txtPulling.setNativeProps({style: hide});
this.txtPullok && this.txtPullok.setNativeProps({style: hide});
this.txtPullrelease && this.txtPullrelease.setNativeProps({style: show});
}
}, 1);
return (
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 60,zIndex:1}}>
<ActivityIndicator size="small" color="red" />
<View ref={(c) => {this.txtPulling = c;}}>
<Text>继续下拉刷新...</Text>
</View>
<View ref={(c) => {this.txtPullok = c;}}>
<Text>松开刷新......</Text>
</View>
<View ref={(c) => {this.txtPullrelease = c;}}>
<Text>刷新中......</Text>
</View>
</View>
);
}
render() {
return (
<PullList
//FlatList基本属性
data={this.state.data}
renderItem={({item,index})=>this.renderItem(item,index)}
keyExtractor={(item, index) => item.toString()}
//FlatList上拉加载更多
ListFooterComponent={()=>this.ListFooterComponent()}
onEndReached={()=>this.loadMore()}
onEndReachedThreshold={0.1}
//PullList下拉刷新
onPullRelease={this.onPullRelease}
topIndicatorRender={this.topIndicatorRender}
topIndicatorHeight={60}
//控制下拉刷新状态的属性,为true时显示头部刷新组件,为false则隐藏
isRefreshing={this.state.isRefreshing}
/>
);
}
onPullRelease(resolve) {
this.setState({isRefreshing:true});
//do something
setTimeout(() => {
//真实情况下,应在请求网络数据后的回调中修改isRefreshing
this.setState({isRefreshing:false})
}, 2000);
}
renderItem(item,index) {
return (
<View style={{height: 100, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize:30}}>{item}</Text>
</View>
);
}
ListFooterComponent=()=>{
const {isLoadMore}=this.state;
if(isLoadMore) {
return (
<View style={{ height: px2dp(80), alignItems: 'center', justifyContent: 'center', flexDirection: 'row' }}>
<ActivityIndicator size="small" color="red"/>
<Text style={{ fontSize: 25, marginLeft: 5 }}>{'正在加载中……'}</Text>
</View>
)
}else return <View/>
};
loadMore=()=>{
if(!this.state.isLoadMore) {
this.setState({ isLoadMore: true });
//do something
//真实情况下,应在请求网络数据后的回调中修改isLoadMore
setTimeout(() => {
this.requestData(3);
this.setState({ isLoadMore: false })
}, 3000);
}
};
requestData=(dataLength)=>{
let currentLength=this.state.data.length;
for(let i=currentLength;i<currentLength+dataLength;i++) {
this.state.data.push(i)
}
}
}