Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - import android.animation.Animator;
 - import android.animation.AnimatorListenerAdapter;
 - import android.animation.ValueAnimator;
 - import android.content.DialogInterface;
 - import android.graphics.Rect;
 - import android.os.SystemClock;
 - import android.support.annotation.NonNull;
 - import android.support.v7.widget.RecyclerView;
 - import android.util.Log;
 - import android.view.MotionEvent;
 - import android.view.VelocityTracker;
 - import android.view.View;
 - import android.view.ViewConfiguration;
 - import android.view.ViewGroup;
 - import android.widget.ListView;
 - import java.util.ArrayList;
 - import java.util.Collections;
 - import java.util.List;
 - import cn.pedant.SweetAlert.SweetAlertDialog;
 - public class SwipeableRecyclerViewTouchListener implements RecyclerView.OnItemTouchListener {
 - // Cached ViewConfiguration and system-wide constant values
 - private int mSlop;
 - private int mMinFlingVelocity;
 - private int mMaxFlingVelocity;
 - private long mAnimationTime;
 - // Fixed properties
 - private RecyclerView mRecyclerView;
 - private SwipeListener mSwipeListener;
 - private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
 - // Transient properties
 - private List<PendingDismissData> mPendingDismisses = new ArrayList<>();
 - private int mDismissAnimationRefCount = 0;
 - private float mDownX;
 - private float mDownY;
 - private boolean mSwiping;
 - private int mSwipingSlop;
 - private VelocityTracker mVelocityTracker;
 - private int mDownPosition;
 - private View mDownView;
 - private boolean mPaused;
 - private float mFinalDelta;
 - /**
 - * Constructs a new swipe touch listener for the given {@link android.support.v7.widget.RecyclerView}
 - *
 - * @param recyclerView The recycler view whose items should be dismissable by swiping.
 - * @param listener The listener for the swipe events.
 - */
 - public SwipeableRecyclerViewTouchListener(RecyclerView recyclerView, SwipeListener listener) {
 - ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext());
 - mSlop = vc.getScaledTouchSlop();
 - mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
 - mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
 - mAnimationTime = recyclerView.getContext().getResources().getInteger(
 - android.R.integer.config_shortAnimTime);
 - mRecyclerView = recyclerView;
 - mSwipeListener = listener;
 - /**
 - * This will ensure that this SwipeableRecyclerViewTouchListener is paused during list view scrolling.
 - * If a scroll listener is already assigned, the caller should still pass scroll changes through
 - * to this listener.
 - */
 - mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
 - @Override
 - public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
 - setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING);
 - }
 - @Override
 - public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
 - }
 - });
 - }
 - /**
 - * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
 - *
 - * @param enabled Whether or not to watch for gestures.
 - */
 - public void setEnabled(boolean enabled) {
 - mPaused = !enabled;
 - }
 - @Override
 - public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
 - return handleTouchEvent(motionEvent);
 - }
 - @Override
 - public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
 - handleTouchEvent(motionEvent);
 - }
 - private boolean handleTouchEvent(MotionEvent motionEvent) {
 - if (mViewWidth < 2) {
 - mViewWidth = mRecyclerView.getWidth();
 - }
 - switch (motionEvent.getActionMasked()) {
 - case MotionEvent.ACTION_DOWN: {
 - if (mPaused) {
 - break;
 - }
 - // Find the child view that was touched (perform a hit test)
 - Rect rect = new Rect();
 - int childCount = mRecyclerView.getChildCount();
 - int[] listViewCoords = new int[2];
 - mRecyclerView.getLocationOnScreen(listViewCoords);
 - int x = (int) motionEvent.getRawX() - listViewCoords[0];
 - int y = (int) motionEvent.getRawY() - listViewCoords[1];
 - View child;
 - for (int i = 0; i < childCount; i++) {
 - child = mRecyclerView.getChildAt(i);
 - child.getHitRect(rect);
 - if (rect.contains(x, y)) {
 - mDownView = child;
 - break;
 - }
 - }
 - if (mDownView != null) {
 - mDownX = motionEvent.getRawX();
 - mDownY = motionEvent.getRawY();
 - mDownPosition = mRecyclerView.getChildPosition(mDownView);
 - if (mSwipeListener.canSwipe(mDownPosition)) {
 - mVelocityTracker = VelocityTracker.obtain();
 - mVelocityTracker.addMovement(motionEvent);
 - } else {
 - mDownView = null;
 - }
 - }
 - break;
 - }
 - case MotionEvent.ACTION_CANCEL: {
 - if (mVelocityTracker == null) {
 - break;
 - }
 - if (mDownView != null && mSwiping) {
 - // cancel
 - mDownView.animate()
 - .translationX(0)
 - .alpha(1)
 - .setDuration(mAnimationTime)
 - .setListener(null);
 - }
 - mVelocityTracker.recycle();
 - mVelocityTracker = null;
 - mDownX = 0;
 - mDownY = 0;
 - mDownView = null;
 - mDownPosition = ListView.INVALID_POSITION;
 - mSwiping = false;
 - break;
 - }
 - case MotionEvent.ACTION_UP: {
 - if (mVelocityTracker == null) {
 - break;
 - }
 - mFinalDelta = motionEvent.getRawX() - mDownX;
 - mVelocityTracker.addMovement(motionEvent);
 - mVelocityTracker.computeCurrentVelocity(1000);
 - float velocityX = mVelocityTracker.getXVelocity();
 - float absVelocityX = Math.abs(velocityX);
 - float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
 - boolean dismiss = false;
 - boolean dismissRight = false;
 - if (Math.abs(mFinalDelta) > mViewWidth / 2 && mSwiping) {
 - dismiss = true;
 - dismissRight = mFinalDelta > 0;
 - } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
 - && absVelocityY < absVelocityX && mSwiping) {
 - // dismiss only if flinging in the same direction as dragging
 - dismiss = (velocityX < 0) == (mFinalDelta < 0);
 - dismissRight = mVelocityTracker.getXVelocity() > 0;
 - }
 - if(!dismiss) {
 - mDownView.animate()
 - .translationX(0)
 - .alpha(1)
 - .setDuration(mAnimationTime)
 - .setListener(null);
 - mVelocityTracker.recycle();
 - mVelocityTracker = null;
 - mDownX = 0;
 - mDownY = 0;
 - mDownView = null;
 - mDownPosition = ListView.INVALID_POSITION;
 - mSwiping = false;
 - Log.d("if!dismiss", "here now");
 - }
 - if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
 - // dismiss
 - final View downView = mDownView; // mDownView gets null'd before animation ends
 - final int downPosition = mDownPosition;
 - ++mDismissAnimationRefCount;
 - final SweetAlertDialog dialog = new SweetAlertDialog(mRecyclerView.getContext(), SweetAlertDialog.WARNING_TYPE);
 - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
 - @Override
 - public void onDismiss(DialogInterface dialog) {
 - mRecyclerView.invalidateItemDecorations();
 - }
 - });
 - final boolean finalDismissRight = dismissRight;
 - dialog
 - .setTitleText("Are you sure?")
 - .setContentText("Won't be able to recover this file!")
 - .setCancelText("No,cancel plx!")
 - .setConfirmText("Yes,delete it!")
 - .showCancelButton(true)
 - .setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
 - @Override
 - public void onClick(SweetAlertDialog sDialog) {
 - sDialog.dismiss();
 - dialog.dismiss();
 - if(mDownView != null) {
 - mDownView.animate()
 - .translationX(0)
 - .alpha(1)
 - .setDuration(mAnimationTime)
 - .setListener(null);
 - Log.d("CancelClickListener", "If statement");
 - mRecyclerView.invalidateItemDecorations();
 - }
 - else {
 - downView.animate()
 - .translationX(0)
 - .alpha(1)
 - .setDuration(mAnimationTime)
 - .setListener(null);
 - Log.d("CancelClickListener", "Else statement");
 - mRecyclerView.invalidateItemDecorations();
 - }
 - mVelocityTracker.recycle();
 - mVelocityTracker = null;
 - mDownX = 0;
 - mDownY = 0;
 - mDownView = null;
 - mDownPosition = ListView.INVALID_POSITION;
 - mSwiping = false;
 - Log.d("CancelClickListener", "After if and else statement");
 - mRecyclerView.invalidateItemDecorations();
 - sDialog.dismiss();
 - }
 - })
 - .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
 - @Override
 - public void onClick(SweetAlertDialog sweetAlertDialog) {
 - dialog.cancel();
 - new SweetAlertDialog(sweetAlertDialog.getContext(), SweetAlertDialog.SUCCESS_TYPE)
 - .setTitleText("Good job!")
 - .setContentText("You clicked the button!")
 - .show();
 - mDownView.animate()
 - .translationX(finalDismissRight ? mViewWidth : -mViewWidth)
 - .alpha(0)
 - .setDuration(mAnimationTime)
 - .setListener(new AnimatorListenerAdapter() {
 - @Override
 - public void onAnimationEnd(Animator animation) {
 - performDismiss(downView, downPosition);
 - Log.d("ConfirmClickListener", "OnAnimationEnd");
 - }
 - });
 - mVelocityTracker.recycle();
 - mVelocityTracker = null;
 - mDownX = 0;
 - mDownY = 0;
 - mDownView = null;
 - mDownPosition = ListView.INVALID_POSITION;
 - mSwiping = false;
 - Log.d("ConfirmClickListener", "last statement");
 - }
 - })
 - .show();
 - }
 - break;
 - }
 - case MotionEvent.ACTION_MOVE: {
 - if (mVelocityTracker == null || mPaused) {
 - break;
 - }
 - mVelocityTracker.addMovement(motionEvent);
 - float deltaX = motionEvent.getRawX() - mDownX;
 - float deltaY = motionEvent.getRawY() - mDownY;
 - if (!mSwiping && Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
 - mSwiping = true;
 - mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
 - }
 - if (mSwiping) {
 - mDownView.setTranslationX(deltaX - mSwipingSlop);
 - mDownView.setAlpha(Math.max(0f, Math.min(1f,
 - 1f - Math.abs(deltaX) / mViewWidth)));
 - return true;
 - }
 - break;
 - }
 - }
 - return false;
 - }
 - private void performDismiss(final View dismissView, final int dismissPosition) {
 - // Animate the dismissed list item to zero-height and fire the dismiss callback when
 - // all dismissed list item animations have completed. This triggers layout on each animation
 - // frame; in the future we may want to do something smarter and more performant.
 - final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
 - final int originalHeight = dismissView.getHeight();
 - ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
 - animator.addListener(new AnimatorListenerAdapter() {
 - @Override
 - public void onAnimationEnd(Animator animation) {
 - --mDismissAnimationRefCount;
 - if (mDismissAnimationRefCount == 0) {
 - // No active animations, process all pending dismisses.
 - // Sort by descending position
 - Collections.sort(mPendingDismisses);
 - int[] dismissPositions = new int[mPendingDismisses.size()];
 - for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
 - dismissPositions[i] = mPendingDismisses.get(i).position;
 - }
 - if (mFinalDelta > 0) {
 - mSwipeListener.onDismissedBySwipeRight(mRecyclerView, dismissPositions);
 - } else {
 - mSwipeListener.onDismissedBySwipeLeft(mRecyclerView, dismissPositions);
 - }
 - // Reset mDownPosition to avoid MotionEvent.ACTION_UP trying to start a dismiss
 - // animation with a stale position
 - mDownPosition = ListView.INVALID_POSITION;
 - ViewGroup.LayoutParams lp;
 - for (PendingDismissData pendingDismiss : mPendingDismisses) {
 - // Reset view presentation
 - pendingDismiss.view.setAlpha(1f);
 - pendingDismiss.view.setTranslationX(0);
 - lp = pendingDismiss.view.getLayoutParams();
 - lp.height = originalHeight;
 - pendingDismiss.view.setLayoutParams(lp);
 - }
 - // Send a cancel event
 - long time = SystemClock.uptimeMillis();
 - MotionEvent cancelEvent = MotionEvent.obtain(time, time,
 - MotionEvent.ACTION_CANCEL, 0, 0, 0);
 - mRecyclerView.dispatchTouchEvent(cancelEvent);
 - mPendingDismisses.clear();
 - }
 - }
 - });
 - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 - @Override
 - public void onAnimationUpdate(ValueAnimator valueAnimator) {
 - lp.height = (Integer) valueAnimator.getAnimatedValue();
 - dismissView.setLayoutParams(lp);
 - }
 - });
 - mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
 - animator.start();
 - }
 - /**
 - * The callback interface used by {@link SwipeableRecyclerViewTouchListener} to inform its client
 - * about a swipe of one or more list item positions.
 - */
 - public interface SwipeListener {
 - /**
 - * Called to determine whether the given position can be swiped.
 - */
 - boolean canSwipe(int position);
 - /**
 - * Called when the item has been dismissed by swiping to the left.
 - *
 - * @param recyclerView The originating {@link android.support.v7.widget.RecyclerView}.
 - * @param reverseSortedPositions An array of positions to dismiss, sorted in descending
 - * order for convenience.
 - */
 - void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions);
 - /**
 - * Called when the item has been dismissed by swiping to the right.
 - *
 - * @param recyclerView The originating {@link android.support.v7.widget.RecyclerView}.
 - * @param reverseSortedPositions An array of positions to dismiss, sorted in descending
 - * order for convenience.
 - */
 - void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions);
 - }
 - class PendingDismissData implements Comparable<PendingDismissData> {
 - public int position;
 - public View view;
 - public PendingDismissData(int position, View view) {
 - this.position = position;
 - this.view = view;
 - }
 - @Override
 - public int compareTo(@NonNull PendingDismissData other) {
 - // Sort by descending position
 - return other.position - position;
 - }
 - }
 - }
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment