In my app, I have to move views anywhere on the layout. So I used onTouchListener
. On onClick
and onLongClick
, I have to perform some other tasks. I am able to move the views. But, the listeners are conflicting with each other. When I move the views, then, sometimes, either onClick
or onLongClick
are invoked. And, I don't want them to be called, when user is moving the view. How can I avoid this? I had referred this link to crosscheck my code. But, couldn't found the mistake. Below is my code:
OnTouch of view
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;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isMoved
&& event.getAction() != MotionEvent.ACTION_UP) {
ViewGroup vg = (ViewGroup) v
.getParent();
draggedViewIndex = vg.indexOfChild(v);
ClipData data = ClipData.newPlainText(
"", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
v);
v.startDrag(data, shadowBuilder, v, 0);
v.setVisibility(View.INVISIBLE);
Animation slideUp = AnimationUtils
.loadAnimation(
WMMBFragmentContainerActivity.this,
R.anim.slide_up_dialog);
crossImage.setVisibility(View.VISIBLE);
crossImage.startAnimation(slideUp);
}
}
});
}
}, 1000);
break;
}
case MotionEvent.ACTION_MOVE: {
Log.e(TAG, "ACTION_MOVE");
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v
.getLayoutParams();
params.leftMargin = (int) initialTouchX - deltaX;
params.topMargin = (int) initialTouchY - deltaY;
v.setLayoutParams(params);
isMoved = true;
break;
}
case MotionEvent.ACTION_UP: {
Log.e(TAG, "ACTION_UP");
initialTouchX = 0;
initialTouchY = 0;
deltaX = 0;
deltaY = 0;
if (!isMoved) {
Log.e(TAG, "ACTION_UP if");
showRunningTransactionFragment(mBroList
.get(draggedViewIndex));
} else {
Log.e(TAG, "ACTION_UP else");
isMoved = false;
}
break;
}
default:
Log.e(TAG, "default");
return result;
}
relBroCircle.invalidate();
Log.e(TAG, "defaultqqq ");
return true;
}
});
Update 1:
So, as per Viswanath's suggestion below, I modified my code. But, still I am facing problem. When, I move the views in onTouch
, sometimes, the code which I wrote in the handler gets executed. I don't want this to be executed when the user moves the view. I want to make it smooth as Facebook messenger ChatHeads
. Their, onClick or onLongClick
are called only, when user wants to perform them. I am not getting where did I made mistake.
Update 2:
Now, I had removed multiple listeners and tried to do all my desired operations in onTouch
. Its working except one problem. Even if I click on the view(I hadn't moved the view till now), ACTION_MOVE
gets called and, thus isMoved
becomes true. So, in this case, the code inside if block
in ACTION_UP
never gets executed. To find out whether I did something wrong, I created a dummy project, chose a textview
and added onTouchListener
and onClickListener
to it. Then, performed click operation. There also, I found that ACTION_MOVE
was called first prior to onClick
then code inside onClick
was executed. So, how can I get onClick
effect with this? I had updated my code.