Recently I had to implement a UI where the user dragged a single UI element. The tasked seemed simple enough on the surface, however, I wanted to be able to respond to the drag and take certain actions depending on the drag direction. After a bit of search I stumbled across the ViewDragHelper, which provides all the callbacks I needed to react to the movements. With some modifications, we can also make it work for our single touch point use case.
Implementing the ViewDragHelper is fairly straightforward. You start by creating a custom ViewGroup and initialize the ViewDragHelper in onAttachToWindow()
Next, we’re going to need a few things to handle the single touch point. First, we need to know if the user is interacting with the screen on the drag target.
This method is fairly straight forward, dragTarget is our indicator and we want to get it’s location on the screen and check if the origin of the motion event is within the bounds of the view. I’ve added a little padding (10 pixels) just to make it a little bit forgiving.
Next, we’ll need to keep track of where the user touched when they started dragging.
We also need to override onInterceptTouchEvent, so that the ViewDragHelper can take control.
The last piece of the puzzle is to implement the DragHelperCallback class, lets look at a few key methods:
This is the method that’s used to track the movement of the view. It’s important to remember that the positions referenced are from the origin of the view that is moving, which is our custom view. In our case, we’re tracking a single touch point, so we need to take the delta and add it to the original position of the touch, this becomes our “draggingBorder”
This method is called when the view begins to drag or stops dragging. We can do some checks in this method to see if certain conditions are met.
Finally we’ll look at onViewReleased. This method is called when the user stops interacting with the view. In our case, we’re looking for the user to drag a certain distance to the left or right. First, we’ll check if they moved at all, then if they are sitting on the boundaries of those distances. If neither of those holds true, we’ll check to see if the velocity was over a certain threshold or if they traveled further than the left and right boundaries we set. At the end, we’ll settle the view back to a resting place.
The ViewDragHelper also requires use to override the computeScroll method of our custom view, the helper uses this method when settling the view in onViewReleased
That’s all folks
Just those 8 methods should be enough to get you on your way with the ViewDragHelper, it really makes complex view dragging a simple task. It’s even easier if you’re not restricting yourself to a single touch point. For some more information on ViewDragHelper you should check out this post by Federico Paolinelli and this one Flavien Laurent, I found both to be extremely useful.