title: Swiping delete on ListView item in a fragment not in activity
body: <p>My Aim is to delete the list-view item by swiping in a fragment. Here iam trying to delete the call history Which is in right side</p>
  
  <p><img src="https://i.stack.imgur.com/hqsKr.png" alt="enter image description here"></p>
  
  <p>I followed <a href="https://stackoverflow.com/questions/6151290/onfling-in-a-listview-get-the-swiped-item-info">OnFling in a ListView, Get the swiped Item info</a></p>
  
  <p>"but i am always getting <strong>MotionEvent e1</strong> null in the method onFling(MotionEvent e1, MotionEvent e2)" </p>
  
  <p>and finally i came to know that it is works in MainActivity and then I follwed the below links to get it</p>
  
  <p><a href="https://github.com/romannurik/Android-SwipeToDismiss" rel="nofollow noreferrer">https://github.com/romannurik/Android-SwipeToDismiss</a></p>
  
  <p>Here i am going to delete item properly but my problem is <strong>"swiping is not happening rgularly. means if i do swiping 10 times , it is hapeening 2 or 3 times"</strong></p>
  
  <p>here is my code in <strong>DialerFragment.java</strong></p>
  
  <pre><code>final SwipeDismissListViewTouchListener swipeDismissTouchListener;
  
      swipeDismissTouchListener = new SwipeDismissListViewTouchListener(listView,
              new SwipeDismissListViewTouchListener.DismissCallbacks() {
                  public boolean canDismiss(int position) {
                      return true;
                  }
  
                  public void onDismiss(ListView listView, int[] reverseSortedPositions) {
                      long[] selectedIds = null;
                      /*
                       * Code to delete
                      */
                  }
              });
  
      listView.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View view, MotionEvent motionEvent) {
              return swipeDismissTouchListener.onTouch(view, motionEvent);
  
          }
      });
  
      listView.setOnScrollListener(swipeDismissTouchListener.makeScrollListener());
  </code></pre>
  
  <p>and another class <strong>SwipeDismissListViewTouchListener.java</strong></p>
  
  <pre><code>public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
  // Cached ViewConfiguration and system-wide constant values
  private int mSlop;
  private int mMinFlingVelocity;
  private int mMaxFlingVelocity;
  private long mAnimationTime;
  
  // Fixed properties
  private ListView mListView;
  private DismissCallbacks mCallbacks;
  private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
  
  // Transient properties
  private List&lt;PendingDismissData&gt; mPendingDismisses = new ArrayList&lt;PendingDismissData&gt;();
  private int mDismissAnimationRefCount = 0;
  private float mDownX;
  private boolean mSwiping;
  private VelocityTracker mVelocityTracker;
  private int mDownPosition;
  private View mDownView;
  private boolean mPaused;
  
  /**
   * The callback interface used by {@link SwipeDismissListViewTouchListener} to inform its client
   * about a successful dismissal of one or more list item positions.
   */
  public interface DismissCallbacks {
      /**
       * Called to determine whether the given position can be dismissed.
       */
      boolean canDismiss(int position);
  
      /**
       * Called when the user has indicated they she would like to dismiss one or more list item
       * positions.
       *
       * @param listView               The originating {@link ListView}.
       * @param reverseSortedPositions An array of positions to dismiss, sorted in descending
       *                               order for convenience.
       */
      void onDismiss(ListView listView, int[] reverseSortedPositions);
  }
  
  /**
   * Constructs a new swipe-to-dismiss touch listener for the given list view.
   *
   * @param listView  The list view whose items should be dismissable.
   * @param callbacks The callback to trigger when the user has indicated that she would like to
   *                  dismiss one or more list items.
   */
  public SwipeDismissListViewTouchListener(ListView listView, DismissCallbacks callbacks) {
      ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
      mSlop = vc.getScaledTouchSlop();
      mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
      mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
      mAnimationTime = listView.getContext().getResources().getInteger(
              android.R.integer.config_shortAnimTime);
      mListView = listView;
      mCallbacks = callbacks;
  }
  
  /**
   * 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;
  }
  
  /**
   * Returns an {@link AbsListView.OnScrollListener} to be added to the {@link
   * ListView} using {@link ListView#setOnScrollListener(AbsListView.OnScrollListener)}.
   * If a scroll listener is already assigned, the caller should still pass scroll changes through
   * to this listener. This will ensure that this {@link SwipeDismissListViewTouchListener} is
   * paused during list view scrolling.&lt;/p&gt;
   *
   * @see SwipeDismissListViewTouchListener
   */
  public AbsListView.OnScrollListener makeScrollListener() {
      return new AbsListView.OnScrollListener() {
          @Override
          public void onScrollStateChanged(AbsListView absListView, int scrollState) {
              setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
          }
  
          @Override
          public void onScroll(AbsListView absListView, int i, int i1, int i2) {
          }
      };
  }
  
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
      if (mViewWidth &lt; 2) {
          mViewWidth = mListView.getWidth();
      }
  
      switch (motionEvent.getActionMasked()) {
          case MotionEvent.ACTION_DOWN: {
              if (mPaused) {
                  return false;
              }
  
              // TODO: ensure this is a finger, and set a flag
  
              // Find the child view that was touched (perform a hit test)
              Rect rect = new Rect();
              int childCount = mListView.getChildCount();
              int[] listViewCoords = new int[2];
              mListView.getLocationOnScreen(listViewCoords);
              int x = (int) motionEvent.getRawX() - listViewCoords[0];
              int y = (int) motionEvent.getRawY() - listViewCoords[1];
              View child;
              for (int i = 0; i &lt; childCount; i++) {
                  child = mListView.getChildAt(i);
                  child.getHitRect(rect);
                  if (rect.contains(x, y)) {
                      mDownView = child;
                      break;
                  }
              }
  
              if (mDownView != null) {
                  mDownX = motionEvent.getRawX();
                  mDownPosition = mListView.getPositionForView(mDownView);
                  if (mCallbacks.canDismiss(mDownPosition)) {
                      mVelocityTracker = VelocityTracker.obtain();
                      mVelocityTracker.addMovement(motionEvent);
                  } else {
                      mDownView = null;
                  }
              }
              view.onTouchEvent(motionEvent);
              return true;
          }
  
          case MotionEvent.ACTION_UP: {
              if (mVelocityTracker == null) {
                  break;
              }
  
              float deltaX = 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(deltaX) &gt; mViewWidth / 2) {
                  dismiss = true;
                  dismissRight = deltaX &gt; 0;
              } else if (mMinFlingVelocity &lt;= absVelocityX &amp;&amp; absVelocityX &lt;= mMaxFlingVelocity
                      &amp;&amp; absVelocityY &lt; absVelocityX) {
                  // dismiss only if flinging in the same direction as dragging
                  dismiss = (velocityX &lt; 0) == (deltaX &lt; 0);
                  dismissRight = mVelocityTracker.getXVelocity() &gt; 0;
              }
              if (dismiss) {
                  // dismiss
                  final View downView = mDownView; // mDownView gets null'd before animation ends
                  final int downPosition = mDownPosition;
                  ++mDismissAnimationRefCount;
                  mDownView.animate()
                          .translationX(dismissRight ? mViewWidth : -mViewWidth)
                          .alpha(0)
                          .setDuration(mAnimationTime)
                          .setListener(new AnimatorListenerAdapter() {
                              @Override
                              public void onAnimationEnd(Animator animation) {
                                  performDismiss(downView, downPosition);
                              }
                          });
              } else {
                  // cancel
                  mDownView.animate()
                          .translationX(0)
                          .alpha(1)
                          .setDuration(mAnimationTime)
                          .setListener(null);
              }
              mVelocityTracker.recycle();
              mVelocityTracker = null;
              mDownX = 0;
              mDownView = null;
              mDownPosition = ListView.INVALID_POSITION;
              mSwiping = false;
              break;
          }
  
          case MotionEvent.ACTION_MOVE: {
              if (mVelocityTracker == null || mPaused) {
                  break;
              }
  
              mVelocityTracker.addMovement(motionEvent);
              float deltaX = motionEvent.getRawX() - mDownX;
              if (Math.abs(deltaX) &gt; mSlop) {
                  mSwiping = true;
                  mListView.requestDisallowInterceptTouchEvent(true);
  
                  // Cancel ListView's touch (un-highlighting the item)
                  MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
                  cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
                          (motionEvent.getActionIndex()
                                  &lt;&lt; MotionEvent.ACTION_POINTER_INDEX_SHIFT));
                  mListView.onTouchEvent(cancelEvent);
                  cancelEvent.recycle();
              }
  
              if (mSwiping) {
                  mDownView.setTranslationX(deltaX);
                  mDownView.setAlpha(Math.max(0f, Math.min(1f,
                          1f - 2f * Math.abs(deltaX) / mViewWidth)));
                  return true;
              }
              break;
          }
      }
      return false;
  }
  
  class PendingDismissData implements Comparable&lt;PendingDismissData&gt; {
      public int position;
      public View view;
  
      public PendingDismissData(int position, View view) {
          this.position = position;
          this.view = view;
      }
  
      @Override
      public int compareTo(PendingDismissData other) {
          // Sort by descending position
          return other.position - position;
      }
  }
  
  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 &gt;= 0; i--) {
                      dismissPositions[i] = mPendingDismisses.get(i).position;
                  }
                  mCallbacks.onDismiss(mListView, dismissPositions);
  
                  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);
                  }
  
                  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();
  }
  </code></pre>
  
  <p>}</p>