在考虑实现自定义的下拉刷新组件的时候,首先要明确,这个算是一种hack方案。并非说自定义的有多么好,反而自定义的下拉刷新在
android
下会有细微的卡顿(我这种实现方式)。因此尽可能仍是用小程序自带的吧。html这个实现主要是参考艾伦大佬的组件。android
咱们将页面分为下面的结构ios
正常的时候下拉刷新区域的高度为0
。git
而后咱们经过scroll-view
的scrollToUpeper
事件来标记开始下滑。github
经过touchstart
来记录咱们手指的初始位置。typescript
经过监听列表区域的touchmove
事件,来不断的计算手指移动距离。小程序
touchend
事件来触发更新事件。性能
咱们将页面分为几种状态:flex
enum refreshStatus {
INIT,
PULL_DOWN,
READY_REFRESH,
LOADING,
DONE
}
复制代码
大体流程以下:this
页面加载以后是INIT
状态。
当触发了scroll-view
的scrollToUpeper
事件,咱们记录一个标志位isUpper
,在scroll-view
的scroll
事件触发时,isUpper
记为false
当咱们列表页滑倒顶部的时候再下拉,页面进入了PULL_DOWN
状态。 通常会设置一个有效的下拉距离,称之为validHeight
,当下拉的高度不足validHeight
时,这时候松开手指,页面回弹不刷新。
当咱们继续下拉,距离超过了validHeight
这时候进入了READY_REFRESH
状态。
在READY_REFRESH
状态的时候放开手指,页面刷新,进入LOADING
状态。
页面刷新完毕以后,进入DONE
状态,刷新区域高度变为0
咱们还须要设置一个最大下拉高度,以及在READY_REFRESH
状态,手指放开后回弹到刷新区域的最大高度。
至此咱们能够写出touchend
、touchstart
、touchmove
代码大体以下:(详细代码)
handleTouchMove(e) {
const curTouch = e.touches[0]
const moveY = (curTouch.pageY - this.lastTouchY) * .3
if(
!this.isUpper ||
moveY < 0 ||
moveY > 2 * this.maxHeight ||
this.state.refreshStatu === refreshStatus.LOADING
) {
return
}
if(moveY < this.validHeight) {
this.setState({
refreshHeight: moveY,
refreshStatu: refreshStatus.PULL_DOWN
})
} else {
this.setState({
refreshHeight: moveY,
refreshStatu: refreshStatus.READY_REFRESH
})
}
}
handleTouchStart(e) {
const curTouch = e.touches[0]
this.lastTouchY = curTouch.pageY
}
handleTouchEnd() {
this.lastTouchY = 0
if(this.state.refreshStatu === refreshStatus.READY_REFRESH) {
this.setState({
refreshStatu: refreshStatus.LOADING,
refreshHeight: this.maxHeight
})
if (this.props.onRefresh) {
this.props.onRefresh()
}
} else {
this.setState({
refreshHeight: 0
})
}
}
handleScrollToUpeper() {
this.isUpper = true
}
handleScroll() {
this.isUpper = false
}
复制代码
除此以外,咱们还须要在调用的页面上加上disableScroll: true
的配置,以解决ios整个页面跟着下滑的问题。
android下会有稍微的卡顿,ios和模拟器体验比较好。
能够页面局部的下拉刷新。刷新的样式也能够定制化。
其实在ios
下还有一种实现方式,利用的就是ios
的scroll-view
在拉到顶部的时候还能够往下拉(橡皮筋效果),这时候咱们能够把刷新的区域放在scroll-view
但是区域上面。性能上确定要比不断的计算高度来的要好。
可是有两个问题:
不能再页面中局部使用,由于局部使用的话就须要禁用页面滚动,这也跟着禁用了ios的橡皮筋效果,从而使咱们的下拉刷新不能用
手指放开以后有个轻微的回弹效果,虽然无伤大雅,可是感受仍是挺奇怪的。
这种实现方式下次我也贴出来,也能够参照艾伦的博客,他说的比较详细,我也主要是参考他的代码来实现的。