Reputation: 289
I am trying to make an inbox like swipe to select multiple items in a list view. I am able to show a view under the main view and am able to drag the views as well. The problem is trying to get onTouch and onItemClickListener to work together.
1: If i return true in the switch case during ACTION_DOWN the onItemClickListener stops working. If i return false then i can't drag the view, but onItemClickListener is working.
2: While dragging the view the listView is still able to scroll, which makes the onTouch go to ACTION_CANCLE
I am attaching the onTouchListener to the view in the getView() method of the adapter like so:
root.setOnTouchListener(new MySwipeListener);
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
return false;
}
case MotionEvent.ACTION_MOVE: {
upX = event.getX();
float deltaX = downX - upX;
if (Math.abs(deltaX) > MIN_LOCK_DISTANCE && listView != null && !motionInterceptDisallowed) {
listView.onInterceptTouchEvent(event);
listView.requestDisallowInterceptTouchEvent(true);
motionInterceptDisallowed = true;
listView.requestDisallowInterceptTouchEvent(true);
}
if (deltaX > 0) {
holder.viewLeft.setVisibility(View.GONE);
} else {
// if first swiped left and then swiped right
holder.viewLeft.setVisibility(View.VISIBLE);
}
//holder.mainView.setTranslationX(-(int)deltaX);
if(deltaX < 0) {
holder.mainView.setTranslationX(-(int) deltaX);
}
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
float deltaX = upX - downX;
if (Math.abs(deltaX) > MIN_DISTANCE) {
holder.mainView.setTranslationX(200);
} else {
holder.mainView.setTranslationX(0);
}
if (listView != null) {
listView.requestDisallowInterceptTouchEvent(false);
motionInterceptDisallowed = false;
}
holder.viewLeft.setVisibility(View.VISIBLE);
return false;
}
case MotionEvent.ACTION_CANCEL:{
holder.viewLeft.setVisibility(View.VISIBLE);
holder.mainView.setTranslationX(0);
return false;
}
}
return false;
}
Upvotes: 1
Views: 296
Reputation: 51
Please use GestureDetector like below,
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 120;
@Override
public boolean onDown(MotionEvent e) {
setX((int) e.getX());
setY((int) e.getY());
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD
&& Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
result = true;
} else if (Math.abs(diffY) > SWIPE_THRESHOLD
&& Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
result = true;
} catch (Exception exception) {
exception.printStackTrace();
}
Utils.log("onfling", "val Y:" + velocityY);
return result;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
if (gestureInterface != null && doubleTap) {
gestureInterface.onDoubleTap();
return true;
}
return false;
}
}
Upvotes: 1