How to Use Both Ontouch and Onclick for an Imagebutton

how to use both Ontouch and Onclick for an ImageButton?

Try this, It may help you

No need to set onClick() method onTouch() will handle both the case.

package com.example.demo;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;

public class MainActivity extends Activity {
private GestureDetector gestureDetector;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureDetector = new GestureDetector(this, new SingleTapConfirm());
ImageButton imageButton = (ImageButton) findViewById(R.id.img);

imageButton.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View arg0, MotionEvent arg1) {

if (gestureDetector.onTouchEvent(arg1)) {
// single tap
return true;
} else {
// your code for move and drag
}

return false;
}
});

}

private class SingleTapConfirm extends SimpleOnGestureListener {

@Override
public boolean onSingleTapUp(MotionEvent event) {
return true;
}
}

}

Android: Working with onTouch, onClick and onLongClick Together

Finally, I managed to achieve what I wanted. The solution is based on Viswanath's idea proposed above. Here is my code:

broItemView.setOnTouchListener(new View.OnTouchListener() {
private int deltaX;
private int deltaY;
private float initialTouchX;
private float initialTouchY;
private boolean isMoved;
private int lastTouchX;
private int lastTouchY;

@Override
public boolean onTouch(final View v, final MotionEvent event) {
ViewGroup vg = (ViewGroup) v.getParent();
draggedViewIndex = vg.indexOfChild(v);
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
boolean result = v.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
isMoved = false;
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v
.getLayoutParams();

deltaX = (int) initialTouchX - params.leftMargin;
deltaY = (int) initialTouchY - params.topMargin;

lastTouchX = (int) initialTouchX;
lastTouchY = (int) initialTouchY;
Log.e(TAG, "ACTION_DOWN lasttouchX: " + lastTouchX);
Log.e(TAG, "ACTION_DOWN lasttouchY: " + lastTouchY);
new Handler().postDelayed(new Runnable() {

@Override
public void run() {
runOnUiThread(new Runnable() {

@Override
public void run() {
if (!isMoved
&& event.getAction() != MotionEvent.ACTION_UP) {
//perform LongClickOperation
}
}
});
}
}, 1000);
break;
}

case MotionEvent.ACTION_MOVE: {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v
.getLayoutParams();

params.leftMargin = (int) initialTouchX - deltaX;
params.topMargin = (int) initialTouchY - deltaY;

v.setLayoutParams(params);

break;
}
case MotionEvent.ACTION_UP: {

if ((lastTouchX == (int) initialTouchX)
&& (lastTouchY == (int) initialTouchY)) {
isMoved = false;
} else if ((lastTouchX > (int) initialTouchX)) {
if (((lastTouchX - (int) initialTouchX) <= 10)) {
isMoved = false;
} else {
isMoved = true;
}
} else if ((lastTouchX < (int) initialTouchX)) {
if ((((int) initialTouchX - lastTouchX) <= 10)) {
isMoved = false;
} else {
isMoved = true;
}
} else if ((lastTouchY > (int) initialTouchY)) {
if (((lastTouchY - (int) initialTouchY) <= 10)) {
isMoved = false;
} else {
isMoved = true;
}
} else if ((lastTouchY < (int) initialTouchY)) {
if ((((int) initialTouchY - lastTouchY) <= 10)) {
isMoved = false;
} else {
isMoved = true;
}
} else {
isMoved = true;
}

if (!isMoved) {
//perform onClick operation
} else {
isMoved = false;
}
initialTouchX = 0;
initialTouchY = 0;
deltaX = 0;
deltaY = 0;
break;
}
default:
return result;
}
relBroCircle.invalidate();
return true;
}
});

In the ACTION_UP, I had to add additional checks to determine whether view actually moved or not because, I found that, ACTION_MOVE still called up even when user has simply clicked on the view. I have checked this separately, as I have mentioned Update 2 of my post. And, when I tested my code on a 10" Tablet, then, my onclick code never executed. So, to avoid this problem, I had to write those bunch of codes. But, I don't think its an elegant solution and seems hack to me. If anyone has better solution, then please advise so that I can update my code.

OnClickListener and OnTouchListener collision issues

I'd suggest you use only the OnTouchListener and handling the click case there using something like:

    ImageButton floatingIcon = (ImageButton) findViewById(R.id.floatingIcon);
gestureDetector = new GestureDetector(this, new YourGestureListener());
floatingIcon.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
if (gestureDetector.onTouchEvent(arg1)) {
// A single tap has been made - treat it like a click and consume the event
return true;
} else {
// The MotionEvent is not a click event, handle and decide if the event is consumed
}
return false;
}
});

private class YourGestureListener extends SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent event) {
return true;
}
}

Using both setOnTouchListener and setOnClickListener on a button

Your click listener will never fire because the touch listener is supposed to tell the system when the elemnt was clicked. Yours isn't. Either add a performClick at the appropriate time, or put everything into the touch listener and perform the click on action_up



Related Topics



Leave a reply



Submit