0

I am using following code to drag a View across the screen

 tweatBtn.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float currX,currY; int action = event.getAction(); switch (action ) { case MotionEvent.ACTION_DOWN: { mPrevX = event.getRawX(); mPrevY = event.getRawY(); btnPrevX = tweatBtn.getX(); btnPrevY = tweatBtn.getY(); break; } case MotionEvent.ACTION_MOVE: { Display display = getActivity().getWindowManager().getDefaultDisplay(); int width = display.getWidth() + 80; // deprecated int height = display.getHeight(); // deprecated currX = event.getRawX(); currY = event.getRawY(); if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width) { tweatBtn.setX(btnPrevX + currX - mPrevX); tweatBtn.setY(btnPrevY + currY - mPrevY); } else { if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10)) { tweatBtn.setX(btnPrevX + currX - mPrevX); tweatBtn.setY(btnPrevY + currY - mPrevY); } } break; } case MotionEvent.ACTION_CANCEL: break; case MotionEvent.ACTION_UP: break; } return false; } }); } 

It works fine but sometimes when i lift the Finger it automatically triggers click.How can i improve?

2
  • return true if the event was consumed. replace "break" by "return true". Commented Mar 11, 2015 at 14:14
  • replace true and click will never fire again Commented Mar 11, 2015 at 14:18

1 Answer 1

3

You are returning always false at the end of the code. Which means the touchListener you have set is not handling the touch. Because of if it, View will consider any normal touch as click. What you should do is return True, when the view is dragged, else you should return False

 boolean dragged = false; ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext()); int minTouchSlop = viewConfiguration.getScaledTouchSlop(); ..... public boolean onTouch(View v, MotionEvent event) { float currX,currY; int action = event.getAction(); switch (action ) { case MotionEvent.ACTION_DOWN: { mPrevX = event.getRawX(); mPrevY = event.getRawY(); btnPrevX = tweatBtn.getX(); btnPrevY = tweatBtn.getY(); dragged = false; // global dragged variable break; } case MotionEvent.ACTION_MOVE: { Display display = getActivity().getWindowManager().getDefaultDisplay(); int width = display.getWidth() + 80; // deprecated int height = display.getHeight(); // deprecated currX = event.getRawX(); currY = event.getRawY(); if(Math.abs(currX-mPrevX) > minTouchSlop || Math.abs(currY-mPrevY) > minTouchSlop) dragged = true; // differntiate btw drag or click if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width) { tweatBtn.setX(btnPrevX + currX - mPrevX); tweatBtn.setY(btnPrevY + currY - mPrevY); } else { if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10)) { tweatBtn.setX(btnPrevX + currX - mPrevX); tweatBtn.setY(btnPrevY + currY - mPrevY); } } break; } case MotionEvent.ACTION_CANCEL: break; case MotionEvent.ACTION_UP: break; } return dragged; } 
Sign up to request clarification or add additional context in comments.

4 Comments

there is a little setback with this code. it usually gives approx 1 second delay what should i do
What is getting delayed ?
The opening of new Activity. Let's say i click now, it will take 1-1.5 seconds for the app to open the new activity that is to call OnClickEvent. Also the button moves first few pixels away first
Reasons (1) Delay, because you are overriding onTouchListener, instead you should write custom btn/view(class extending btn/view) and should override onTouchEvent() and perform above logic. Listeners are like redirectors. (2) Icon movement during click: Perform setX and setY only if if(Math.abs(currX-mPrevX) > minTouchSlop || Math.abs(currY-mPrevY) > minTouchSlop) else do nothing

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.