I have a activity which consists of toolbar, bottommenu (similar to instagram) and a small draggable relativeLayout at the right bottom of the screen of width and height = 500dp.
I have implemented drag on that relativeLayout as follows:
public void touchListenerPip(RelativeLayout relativeLayoutPIP) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float screenHeight = displayMetrics.heightPixels;
float screenWidth = displayMetrics.widthPixels;
relativeLayoutPIP.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
float newX, newY;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
newX = event.getRawX() + dX;
newY = event.getRawY() + dY;
if ((newX <= 0 || newX >= screenWidth - view.getWidth()) || (newY <= 0 || newY >= screenHeight - view.getHeight())) {
lastAction = MotionEvent.ACTION_MOVE;
break;
}
//to block the view being dragged out of toolbar
if (newY < (float) toolbar.getHeight()) {
lastAction = MotionEvent.ACTION_MOVE;
break;
}
//to block the view being dragged out of bottombar
if (event.getRawY() + (float) view.getHeight() > screenHeight - (float) bottomBar.getHeight()) {
lastAction = MotionEvent.ACTION_MOVE;
break;
}
view.setX(newX);
view.setY(newY);
lastAction = MotionEvent.ACTION_MOVE;
break;
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN)
break;
default:
return false;
}
return true;
}
});
}
The view is dragging fine and dragging is not smooth. Any suggestions for smooth dragging of view?
Got it to smoothly work with below code and also able to perform click on with
private final static float CLICK_DRAG_TOLERANCE = 10; // Often, there will be a slight, unintentional, drag when the user taps the view, so we need to account for this.
private float downRawX, downRawY;
private float dX, dY;
public void touchListenerPip(RelativeLayout relativeLayoutPIP) {
relativeLayoutPIP.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
downRawX = event.getRawX();
downRawY = event.getRawY();
dX = view.getX() - downRawX;
dY = view.getY() - downRawY;
return true;
} else if (action == MotionEvent.ACTION_MOVE) {
int viewWidth = view.getWidth();
int viewHeight = view.getHeight();
View viewParent = (View) view.getParent();
int parentWidth = viewParent.getWidth();
int parentHeight = viewParent.getHeight();
float newX = event.getRawX() + dX;
newX = Math.max(0, newX); // Don't allow the view past the left hand side of screen
newX = Math.min(parentWidth - viewWidth, newX); // Don't allow the view past the right hand side of screen
float newY = event.getRawY() + dY;
newY = Math.max(toolbar.getHeight(), newY); // Don't allow the view past the top of screen including toolbar
int bottomHeight = viewHeight + bottomBar.getHeight();
newY = Math.min(parentHeight - bottomHeight, newY); // Don't allow the view past the bottom of screen including bottombar
view.animate()
.x(newX)
.y(newY)
.setDuration(0)
.start();
return true;
} else if (action == MotionEvent.ACTION_UP) {
float upRawX = event.getRawX();
float upRawY = event.getRawY();
float upDX = upRawX - downRawX;
float upDY = upRawY - downRawY;
if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
viewClick();
return true;
} else { // A drag
return true;
}
}
return true;
}
});
}