/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.plan.my.mytoolslibrary.swipe;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ScrollerCompat;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import java.util.Arrays;
/**
* ViewDragHelper is a utility class for writing custom ViewGroups. It offers a
* number of useful operations and state tracking for allowing a user to drag
* and reposition views within their parent ViewGroup.
*/
public class ViewDragHelper {
private static final String TAG = "ViewDragHelper";
/**
* A null/invalid pointer ID.
*/
public static final int INVALID_POINTER = -1;
/**
* A view is not currently being dragged or animating as a result of a
* fling/snap.
*/
public static final int STATE_IDLE = 0;
/**
* A view is currently being dragged. The position is currently changing as
* a result of user input or simulated user input.
*/
public static final int STATE_DRAGGING = 1;
/**
* A view is currently settling into place as a result of a fling or
* predefined non-interactive motion.
*/
public static final int STATE_SETTLING = 2;
/**
* Edge flag indicating that the left edge should be affected.
*/
public static final int EDGE_LEFT = 1 << 0;
/**
* Edge flag indicating that the right edge should be affected.
*/
public static final int EDGE_RIGHT = 1 << 1;
/**
* Edge flag indicating that the top edge should be affected.
*/
public static final int EDGE_TOP = 1 << 2;
/**
* Edge flag indicating that the bottom edge should be affected.
*/
public static final int EDGE_BOTTOM = 1 << 3;
/**
* Edge flag set indicating all edges should be affected.
*/
public static final int EDGE_ALL = EDGE_LEFT | EDGE_TOP | EDGE_RIGHT | EDGE_BOTTOM;
/**
* Indicates that a check should occur along the horizontal axis
*/
public static final int DIRECTION_HORIZONTAL = 1 << 0;
/**
* Indicates that a check should occur along the vertical axis
*/
public static final int DIRECTION_VERTICAL = 1 << 1;
/**
* Indicates that a check should occur along all axes
*/
public static final int DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
public static final int EDGE_SIZE = 20; // dp
private static final int BASE_SETTLE_DURATION = 256; // ms
private static final int MAX_SETTLE_DURATION = 600; // ms
// Current drag state; idle, dragging or settling
private int mDragState;
// Distance to travel before a drag may begin
private int mTouchSlop;
// Last known position/pointer tracking
private int mActivePointerId = INVALID_POINTER;
private float[] mInitialMotionX;
private float[] mInitialMotionY;
private float[] mLastMotionX;
private float[] mLastMotionY;
private int[] mInitialEdgeTouched;
private int[] mEdgeDragsInProgress;
private int[] mEdgeDragsLocked;
private int mPointersDown;
private VelocityTracker mVelocityTracker;
private float mMaxVelocity;
private float mMinVelocity;
private int mEdgeSize;
private int mTrackingEdges;
private ScrollerCompat mScroller;
private final Callback mCallback;
private View mCapturedView;
private boolean mReleaseInProgress;
private final ViewGroup mParentView;
/**
* A Callback is used as a communication channel with the ViewDragHelper
* back to the parent view using it. <code>on*</code>methods are invoked on
* siginficant events and several accessor methods are expected to provide
* the ViewDragHelper with more information about the state of the parent
* view upon request. The callback also makes decisions governing the range
* and draggability of child views.
*/
public static abstract class Callback {
/**
* Called when the drag state changes. See the <code>STATE_*</code>
* constants for more information.
*
* @param state The new drag state
* @see #STATE_IDLE
* @see #STATE_DRAGGING
* @see #STATE_SETTLING
*/
public void onViewDragStateChanged(int state) {
}
/**
* Called when the captured view's position changes as the result of a
* drag or settle.
*
* @param changedView View whose position changed
* @param left New X coordinate of the left edge of the view
* @param top New Y coordinate of the top edge of the view
* @param dx Change in X position from the last call
* @param dy Change in Y position from the last call
*/
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
}
/**
* Called when a child view is captured for dragging or settling. The ID
* of the pointer currently dragging the captured view is supplied. If
* activePointerId is identified as {@link #INVALID_POINTER} the capture
* is programmatic instead of pointer-initiated.
*
* @param capturedChild Child view that was captured
* @param activePointerId Pointer id tracking the child capture
*/
public void onViewCaptured(View capturedChild, int activePointerId) {
}
/**
* Called when the child view is no longer being actively dragged. The
* fling velocity is also supplied, if relevant. The velocity values may
* be clamped to system minimums or maximums.
* <p>
* Calling code may decide to fling or otherwise release the view to let
* it settle into place. It should do so using
* {@link #settleCapturedViewAt(int, int)} or
* {@link #flingCapturedView(int, int, int, int)}. If the Callback
* invokes one of these methods, the ViewDragHelper will enter
* {@link #STATE_SETTLING} and the view capture will not fully end until
* it comes to a complete stop. If neither of these methods is invoked
* before <code>onViewReleased</code> returns, the view will stop in
* place and the ViewDragHelper will return to {@link #STATE_IDLE}.
* </p>
*
* @param releasedChild The captured child view now being released
* @param xvel X velocity of the pointer as it left the screen in pixels
* per second.
* @param yvel Y velocity of the pointer as it left the screen in pixels
* per second.
*/
public void onViewReleased(View releasedChild, float xvel, float yvel) {
}
/**
* Called when one of the subscribed edges in the parent view has been
* touched by the user while no child view is currently captured.
*
* @param edgeFlags A combination of edge flags describing the edge(s)
* currently touched
*