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
Intent Action for Network Events in Android Sdk
Detect an Application Is Installed or Not
Call Method When Home Button Pressed
Removing Log Call Using Proguard
Comparing Two Drawables in Android
Android - Nullpointerexception on Searchview in Action Bar
How to Use Custom Font with Webview
Open Failed: Eacces (Permission Denied)
How to Save State During Orientation Change in Android If the State Is Made of My Classes
How to Use Apply a Custom Drawable to Radiobutton
Android Boot_Completed Not Received When Application Is Closed
How to Set Relativelayout Layout Params in Code Not in Xml
How to Disable Past Dates in Android Date Picker
Android Saving Created Bitmap to Directory on Sd Card
How to Make an Application Ignore Screen Orientation Change
Fusedlocationapi.Getlastlocation Always Null
How to Make Alarm Manager Work When Android 6.0 in Doze Mode
Error:'Keytool' Is Not Recognized as an Internal or External Command, Operable Program or Batch File