@Override
  public boolean onTouchEvent(MotionEvent ev) {
    final int action = ev.getAction();
    final int x = (int) ev.getX();
    final int y = (int) ev.getY();

    // [shravan.mahankali] dynamically find the dragger object and let user drag the item
    // only if touched on dragger and not otherwise.
    if (action == MotionEvent.ACTION_DOWN) {
      int startPos = pointToPosition(x, y);
      if (startPos != INVALID_POSITION) {
        int mItemPosition = startPos - getFirstVisiblePosition();
        View grabber = getChildAt(mItemPosition).findViewById(draggerId);
        int mDragPointY = y - grabber.getTop();

        int[] grabberLocationOnScreen = new int[2];
        grabber.getLocationOnScreen(grabberLocationOnScreen);

        if (x >= grabber.getLeft()
            && x <= grabber.getRight()
            && mDragPointY >= grabber.getTop()
            && mDragPointY <= grabberLocationOnScreen[1]) mDragMode = true;
      }
    }

    if (!mDragMode) return super.onTouchEvent(ev);

    switch (action) {
      case MotionEvent.ACTION_DOWN:
        mStartPosition = pointToPosition(x, y);
        if (mStartPosition != INVALID_POSITION) {
          int mItemPosition = mStartPosition - getFirstVisiblePosition();
          mDragPointOffset = y - getChildAt(mItemPosition).getTop();
          mDragPointOffset -= ((int) ev.getRawY()) - y;
          startDrag(mItemPosition, y);
          drag(0, y); // replace 0 with x if desired
        }
        break;
      case MotionEvent.ACTION_MOVE:
        drag(0, y); // replace 0 with x if desired
        break;
      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
      default:
        mDragMode = false;
        mEndPosition = pointToPosition(x, y);
        stopDrag(mStartPosition - getFirstVisiblePosition());
        if (mDropListener != null
            && mStartPosition != INVALID_POSITION
            && mEndPosition != INVALID_POSITION) mDropListener.onDrop(mStartPosition, mEndPosition);
        break;
    }
    return true;
  }
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    final int action = ev.getAction();
    final int x = (int) ev.getX();
    final int y = (int) ev.getY();

    if (action == MotionEvent.ACTION_DOWN && x < 40) {
      mDragMode = true;
    }

    if (!mDragMode) return super.onTouchEvent(ev);

    switch (action) {
      case MotionEvent.ACTION_DOWN:
        mStartPosition = pointToPosition(x, y);
        if (mStartPosition != INVALID_POSITION) {
          int mItemPosition = mStartPosition - getFirstVisiblePosition();
          mDragItemY = getChildAt(mItemPosition).getTop();
          mDragPointOffset = y - mDragItemY;
          mDragPointOffset -= ((int) ev.getRawY()) - y;
          startDrag(mItemPosition, y);
          drag(x, y);
        }
        break;
      case MotionEvent.ACTION_MOVE:
        drag(x, y);
        break;
      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
      default:
        mDragMode = false;
        mEndPosition = pointToPosition(x, y);
        stopDrag(mStartPosition - getFirstVisiblePosition(), x, y);
        if (mDropListener != null
            && mStartPosition != INVALID_POSITION
            && mEndPosition != INVALID_POSITION) mDropListener.onDrop(mStartPosition, mEndPosition);
        break;
    }
    return true;
  }
  // enable the drag view for dragging
  private void startDrag(int itemIndex, int y) {
    stopDrag(itemIndex);

    View item = getChildAt(itemIndex);
    if (item == null) return;
    item.setDrawingCacheEnabled(true);
    if (mDragListener != null) mDragListener.onStartDrag(item);

    // Create a copy of the drawing cache so that it does not get recycled
    // by the framework when the list tries to clean up memory
    Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());

    WindowManager.LayoutParams mWindowParams = new WindowManager.LayoutParams();
    mWindowParams.gravity = Gravity.TOP;
    mWindowParams.x = 0;
    mWindowParams.y = y - mDragPointOffset;

    mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
    mWindowParams.flags =
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
            | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
    mWindowParams.format = PixelFormat.TRANSLUCENT;
    mWindowParams.windowAnimations = 0;

    Context context = getContext();
    ImageView v = new ImageView(context);
    v.setImageBitmap(bitmap);

    WindowManager mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    mWindowManager.addView(v, mWindowParams);
    mDragView = v;
  }