最近一直在做React-Native相关的事情,需要实现一个下拉刷新,Android集成原生很容易,但iOS似乎比较麻烦,于是搅尽脑汁之后,最后根据Github上的下拉刷新库,但这个库并没有实现SectionList的下拉刷新,于是根据该库的代码自己的下拉刷新,为防止以后有需要时忘记或有迷惑,故记录在此。
效果展示
实现步骤
UI布局
首先,是整个UI的布局,也许SectionList有方法只是我不知道,我们知道,在原生开发中,iOS的UITableView可以使用setContentOffset让列表停止在任意的地方,原生下拉刷新的实现也正是依赖于这个属性,通过监听contentOffset,改变对应的状态。但是我在RN里面找不到这样的方法,每次下拉之后只要一放手立马回弹。所以不能直接将下拉刷新控件添加到列表上。之前我也有过这种布局思路,但是不知道怎么拿到列表的偏移量,在发现了这个库以后,我知道了可以用SectionList里面的方法来获取到滚动偏移,其实还有另外一种方法,就是使用onScroll方法。
所以布局如下所示:
render() {
let refreshHeader = <View/>;
if (this.props.RefreshControl !== undefined) {
refreshHeader = this.props.RefreshControl;
} else if (this.props.onRefresh !== undefined) {
refreshHeader =
<MessageRefreshHeader ref={
(ref) => this._refreshHeader = ref}
onRefresh={
this.props.onRefresh} style={
{
transform: [{
translateY: this.state.headerOffset}]}}/>;
}
let refreshFooter = <View/>;
if (this.props.LoadMoreControl !== undefined) {
refreshFooter = this.props.LoadMoreControl;
} else if (this.props.onLoadMore !== undefined) {
refreshFooter =
<MessageRefreshFooter ref={
(ref) => this._refreshFooter = ref} onLoadMore={
this.props.onLoadMore}/>;
}
return (
<View style={
{
flex: 1, flexGrow: 1}} {
...this._panResponder.panHandlers}>
<View pointerEvents='box-none' style={
{
flex: 1}} onLayout={
(e) => {
if(e.nativeEvent.layout.width !== this.state.width || e.nativeEvent.layout.height !== this.state.height) {
this.setState({
width: e.nativeEvent.layout.width,
height: e.nativeEvent.layout.height,
});
}
}}>
<Animated.View
style={
[{
...style.container},
{
width: '100%', height: this.state.height + MessageConstant.refreshHeaderHeight, transform:[{
translateY: this.state.translateY}]}]}>
{
refreshHeader}
<Animated.View ref={
(container) => this._scrollContainer = container} style={
{
flex: 1, transform: [{
translateY: this.state.sectionOffset}]}}>
<SectionList
ref={
sectionList => this._sectionList = sectionList}
initialNumToRender={
3}
keyExtractor={
(item, index) => item + index}
sections={
this.props.sections}
renderItem={
this.props.renderItem}
renderSectionHeader={
this.props.renderSectionHeader}
stickySectionHeadersEnabled={
this.props.stickySectionHeadersEnabled}
ItemSeparatorComponent={
this.props.ItemSeparatorComponent}
scrollEnabled={
true}
bounces={
true}
onScroll={
(e