这里写代码片#Android上仿IOS弹性ScrollView
滑动的原理:由于在ACTION_MOVE
事件中不断获取手指移动的微小的偏移量,这样就将一段距离划分成了N个非常小的偏移量。虽然在每个偏移量里面,通过scrollBy方法进行了瞬间移动,但在整体上却可以获得一个平滑移动效果。
阻尼效果的实现原理:比如你下拉50dp,innerView只移动25dp。从效果上看就好像有个力在阻挠你下拉。
难点:
1. 移动过程中的处理:
MotionEvent.ACTION_MOVE
中,在手指移动过程中,ev.getY()会不断获取当前手指的y坐标。
通过不断的计算前一次y的坐标和现在y坐标的偏移量detailY
,然后把detailY
在传到innerView.layout
中,从而实现了下拉的效果。
2.Rect normal = new Rect()
的作用?
用于记录innerView的原始位置。具体逻辑:在MotionEvent.ACTION_MOVE
中判断normal
为空,把innerView
的四个点存起来。然后在MotionEvent.ACTION_UP
中,即让innerView
弹回原位的动画结束后,为innerView
提供原始位置,并令normal
再次为空。
3.isNeedMove()
方法
作用:判断是否触发弹性移动效果
innerView.getMeasuredHeight()
:获取的是控件的总高度
getHeight()
:获取的是屏幕的高度
当控件的高度<>getScrollY
始终为0.
当控件的高度>屏幕的高度时候,上下滑动innerView
时,getScrollY
才会有变化的值。
针对第一种情况。只要scrollY == 0
就会触发效果。
第二种情况。下拉的触发效果的条件scrollY == 0
,上拉触发效果的条件是scrollY == offset
privatebooleanisNeedMove() {
int offset = innerView.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// 0是顶部,后面那个是底部if (scrollY == 0 || scrollY == offset) {
returntrue;
}
returnfalse;
}
代码: