1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > android 阻尼动画 Android阻尼效果 | 自定义进阶之实现MIUI的拖动视差效果

android 阻尼动画 Android阻尼效果 | 自定义进阶之实现MIUI的拖动视差效果

时间:2023-07-06 04:28:33

相关推荐

android 阻尼动画 Android阻尼效果 | 自定义进阶之实现MIUI的拖动视差效果

原标题:Android阻尼效果 | 自定义进阶之实现MIUI的拖动视差效果

作者:xiaoyanger

来源:/u/25c3b13f87ce

在MIUI上有一些界面在拖动的时候有一个视差效果:

在可以滚动的视图中,内容滚动到顶部时继续下拉,整个视图就有一个竖直方向拉伸的视差效果。滚动到底部继续上拉,也有同样的效果。

滚动视图可能是ScrollView、RecyclerView,要实现这样的效果,需要自定义并拦截Touch事件,重新处理事件逻辑。

以RecyclerView为例,我们自定义一个ParallaxRecyclerView,复写onInterceptTouchEvent方法:

滚动RecyclerView到达顶部或者底部继续拖动时,需要拦截Touch事件。所以在MotionEvent.ACTION_MOVE时需要判断当前RecyclerView是否在顶部或者底部。需要注意的是,当RecyclerView中的item没有填充满整视图时,RecyclerView的状态既是在顶部也是在底部。

mActivePointerId表示在多点触控是当前活动手指的id,mInitialMotionY为手指按下时的Y坐标。

当达到顶部或底部继续拖动时,根据当前的位置(isScrollToTop()、isScrollToBottom())和ACTION_MOVE时的移动距离yDiff来判断是否需要拦截:在顶部时向上拖动并且yDiff>mTouchSlop就需要拦截,底部时向下拖动同样yDiff>mTouchSlop也需要拦截,同时在顶部和底部时满足Math.abs(yDiff)>mTouchSlop也需要拦截。

需要拦截都是在没有被拖动(!isBeingDragged)的情况下。

RecyclerViev既没有在顶部也没有在底部时,说明item滚动到中间,可以上下继续滚动,不需要拦截,交给super.onInterceptTouchEvent(event)来处理。同时其它不需要拦截的情况也都交给super来处理。

onSecondaryPointerUp(event)为当第二个手指离开屏幕是需要重新设置mActivePointerId:

拦截到TouchEvent,在onTouchEven中处理,实现拖动视差效果:

代码虽然有点长,但是逻辑很简单,在拦截到ACTION_MOVE事件后,同样根据顶部或底部位置以及滚动的距离mDistance来确定是否消费掉该事件。不需要消费的直接给`super.onTouchEvent(event)来处理,需要消费的话根据mDistance来计算出缩放的比例mScale,再通过pull(mScale)和push(mScale)来缩放。

在ACTION_UP时,需要将缩放的视图通过动画还原到初始状态。这里也需要判断位置,因为不同位置的的缩放中心点不一样。同时即在顶部也在底部时是根mDistance的正负值来判断拖动的方向。

这样就OK了,如果需要实现ScrollView、ListView、GridView也是一样的逻辑,源码中已经有了ParallaxScrollView的实现,看下最终效果图:

ParallaxRecyclerView:

ParallaxScrollView

源码:

/xiaoyanger0825/Parallax

如果你有想学习的文章直接留言,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我投递文章链接即可。

责任编辑:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。