前言

以前我们想实现一个可拖动的悬浮窗,一般来说需要在ViewGroup的onTouch事件里面处理各种DOWN、MOVE、UP事件,写的很恶心,而且让代码也很难维护,好在现在有一个神器ViewDragHelper来帮我们处理这些情况,感谢Google~~~

ViewDragHelper的基础使用

ViewDragHelper的基本使用如下。首先需要覆写ViewGroup的onInterceptTouchEvent以及onTouchEvent,然后将其交给ViewDragHelper进行处理,然后在ViewDragHelper.Callback中进行各种回调处理。一般来说,需要覆写tryCaptureView,用来告诉ViewDragHelper哪一个View可以被拖动。

拖动效果可以查看Demo.apk

限制拖动范围

上面的代码能让ViewGroup中第一个子View任意拖动,如果我们向让其左右不能出边界,上下可以出边界,就需要改写下clampViewPositionHorizontal、clampViewPositionVertical方法,这两个方法主要是用来修正可被拖动的View即将到达的位置,通过修改这两个函数的返回值,即可限制拖动范围。

加入自动回到起点

首先我们需要知道什么时候用户停止了拖动,这一事件可以在ViewDragHelper.Callback的onViewReleased方法中知道,然后我们ViewDragHelper.settleCapturedViewAt设置View要回到的位置,那么View就会以当前拖动的速度,自动回到指定地点。

并且惯性滑动ViewDragHelper使用的ScrollerCompat实现,所以我们也得覆写computeScroll方法才行,大致逻辑如下(省略部分代码)

解决点击冲突

如果你将可移动的View添加一个点击事件,如果不进行特殊的处理,你会发现点击事件是无效的,所以我们需要如下覆写部分方法

添加屏幕边缘滑动监听

如果我们的View在屏幕中间,我们想让用户滑动屏幕的某一个边缘也行将其滑动,那么就需要添加屏幕边缘滑动监听。

上面的代码就是当用户在屏幕左边滑动的时候,ViewDragHelper会自动回调ViewDragHelper.Callback的onEdgeDragStarted方法,然后我们就可以进行移动处理了。

移动联合动画

如果需要在移动某一个View的时候,另一个view也随之进行某种移动,那么仅仅需要在View移动的时候进行监听,然后同步移动另一个即可,至于如何监听View的移动,ViewDragHelper.CallBack中也有回调。

其他

其实查看ViewDragHelper的源码可以发现,ViewDragHelper移动View是使用的View自带的offsetLeftAndRight以及offsetTopAndBottom,惯性移动使用的ScrollerCompat,主要是将手指的复杂处理给封装起来,便于开发者调用。

顺带贴出能让View进行位移的一些方法。

参考链接:希尔瓦娜斯女神

Demo地址:Github

最后修改日期: 2017年11月7日

作者

留言

挖槽, 沙发了.

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。