Reputation: 288
in the touchListener
below View
's onClick method is called even after a swipe gesture is detected. (no matter left or right)
I've already tried returning true in the end but it blocks the normal clicks from happening as well
public class SwipeDismissTouchListener implements View.OnTouchListener {
private int mSlop;
private int mMinFlingVelocity;
private int mMaxFlingVelocity;
private long mAnimationTime;
private View mView;
private View mBackground;
private TextView mBackgroundText;
private OnDismissCallback mCallback;
private int mViewWidth = 1;
private float mDownX;
private boolean mSwiping;
private Object mToken;
private VelocityTracker mVelocityTracker;
private float mTranslationX;
public interface OnDismissCallback {
void onDismiss(View view, Object token);
void onRightSwipe(View view);
void onLeftSwipe(View view);
}
public SwipeDismissTouchListener(View view, View BackgroundContainer, TextView tvBg, Object token, OnDismissCallback callback) {
ViewConfiguration vc = ViewConfiguration.get(view.getContext());
mSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
mAnimationTime = view.getContext().getResources().getInteger(
android.R.integer.config_shortAnimTime);
mView = view;
mToken = token;
mCallback = callback;
mBackground = BackgroundContainer;
mBackgroundText = tvBg;
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
motionEvent.offsetLocation(mTranslationX, 0);
if (mViewWidth < 2) {
mViewWidth = mView.getWidth();
}
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
mDownX = motionEvent.getRawX();
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(motionEvent);
view.onTouchEvent(motionEvent);
return false;
}
case MotionEvent.ACTION_UP: {
if (mVelocityTracker == null) {
break;
}
final float deltaX = motionEvent.getRawX() - mDownX;
mVelocityTracker.addMovement(motionEvent);
mVelocityTracker.computeCurrentVelocity(1000);
float velocityX = Math.abs(mVelocityTracker.getXVelocity());
float velocityY = Math.abs(mVelocityTracker.getYVelocity());
boolean dismiss = false;
boolean dismissRight = false;
if (Math.abs(deltaX) > mViewWidth / 3 * 2) {
dismiss = true;
dismissRight = deltaX > 0;
} else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity
&& velocityY < velocityX) {
if (Math.abs(deltaX) > mViewWidth / 5) {
dismiss = true;
dismissRight = mVelocityTracker.getXVelocity() > 0;
}
}
if (dismiss) {
mView.animate()
.translationX(dismissRight ? mViewWidth : -mViewWidth)
.alpha(0)
.setDuration(mAnimationTime)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (deltaX > 0) {
mCallback.onRightSwipe(mView);
} else {
mCallback.onLeftSwipe(mView);
}
mView.setX(0);
mView.animate()
.alpha(1)
.setDuration(mAnimationTime)
.setListener(null);
}
});
} else {
mView.animate()
.translationX(0)
.alpha(1)
.setDuration(mAnimationTime)
.setListener(null);
}
mVelocityTracker = null;
mTranslationX = 0;
mDownX = 0;
mSwiping = false;
}
case MotionEvent.ACTION_MOVE: {
if (mVelocityTracker == null) {
break;
}
mVelocityTracker.addMovement(motionEvent);
float deltaX = motionEvent.getRawX() - mDownX;
if (Math.abs(deltaX) > mSlop) {
mSwiping = true;
mView.getParent().requestDisallowInterceptTouchEvent(true);
MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
(motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
mView.onTouchEvent(cancelEvent);
}
if (mSwiping) {
mTranslationX = deltaX;
mView.setTranslationX(deltaX);
if (deltaX > 0) {
mBackground.setBackgroundColor(Color.parseColor("#BD362F"));
mBackgroundText.setText("رد درخواست");
} else {
mBackground.setBackgroundColor(Color.parseColor("#51A361"));
mBackgroundText.setText("تایید درخواست");
}
mView.setAlpha(Math.max(0f, Math.min(1f,
1f - 2f * Math.abs(deltaX / 3 * 2) / mViewWidth)));
return true;
}
break;
}
}
return false;
}
private void performDismiss() {
final ViewGroup.LayoutParams lp = mView.getLayoutParams();
final int originalHeight = mView.getHeight();
ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCallback.onDismiss(mView, mToken);
mView.setAlpha(1f);
mView.setTranslationX(0);
lp.height = originalHeight;
mView.setLayoutParams(lp);
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
lp.height = (Integer) valueAnimator.getAnimatedValue();
mView.setLayoutParams(lp);
}
});
animator.start();
}}
and the listener is applied to a Recyclerview
row.
Upvotes: 1
Views: 683
Reputation:
Change the end of action up event to return true if a swipe is detected
if (mSwiping) {
mSwiping = false;
return true;
}
mSwiping = false;
Upvotes: 3