android 滤镜 仿,Android之仿B612咔叽滤镜列表操作

import android.content.res.Resources;

import android.graphics.Canvas;

import android.graphics.Rect;

import android.os.Build;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.support.v4.animation.AnimatorCompatHelper;

import android.support.v4.animation.AnimatorListenerCompat;

import android.support.v4.animation.AnimatorUpdateListenerCompat;

import android.support.v4.animation.ValueAnimatorCompat;

import android.support.v4.view.GestureDetectorCompat;

import android.support.v4.view.MotionEventCompat;

import android.support.v4.view.VelocityTrackerCompat;

import android.support.v4.view.ViewCompat;

import android.support.v7.recyclerview.R;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.support.v7.widget.RecyclerView.OnItemTouchListener;

import android.support.v7.widget.RecyclerView.ViewHolder;

import android.util.Log;

import android.view.GestureDetector;

import android.view.HapticFeedbackConstants;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.view.ViewGroup;

import android.view.ViewParent;

import android.view.animation.Interpolator;

import java.util.ArrayList;

import java.util.List;

/**

* This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

*

* It works with a RecyclerView and a Callback class, which configures what type of interactions

* are enabled and also receives events when user performs these actions.

*

* Depending on which functionality you support, you should override

* {@link Callback#onMove(RecyclerView, ViewHolder, ViewHolder)} and / or

* {@link Callback#onSwiped(ViewHolder, int)}.

*

* This class is designed to work with any LayoutManager but for certain situations, it can be

* optimized for your custom LayoutManager by extending methods in the

* {@link ItemTouchHelper.Callback} class or implementing {@link ItemTouchHelper.ViewDropHandler}

* interface in your LayoutManager.

*

* By default, ItemTouchHelper moves the items' translateX/Y properties to reposition them. On

* platforms older than Honeycomb, ItemTouchHelper uses canvas translations and View's visibility

* property to move items in response to touch events. You can customize these behaviors by

* overriding {@link Callback#onChildDraw(Canvas, RecyclerView, ViewHolder, float, float, int,

* boolean)}

* or {@link Callback#onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int,

* boolean)}.

*

* Most of the time, you only need to override onChildDraw but due to limitations of

* platform prior to Honeycomb, you may need to implement onChildDrawOver as well.

*/

public class ItemTouchHelper extends RecyclerView.ItemDecoration

implements RecyclerView.OnChildAttachStateChangeListener {

/**

* Up direction, used for swipe & drag control.

*/

public static final int UP = 1;

/**

* Down direction, used for swipe & drag control.

*/

public static final int DOWN = 1 << 1;

/**

* Left direction, used for swipe & drag control.

*/

public static final int LEFT = 1 << 2;

/**

* Right direction, used for swipe & drag control.

*/

public static final int RIGHT = 1 << 3;

// If you change these relative direction values, update Callback#convertToAbsoluteDirection,

// Callback#convertToRelativeDirection.

/**

* Horizontal start direction. Resolved to LEFT or RIGHT depending on RecyclerView's layout

* direction. Used for swipe & drag control.

*/

public static final int START = LEFT << 2;

/**

* Horizontal end direction. Resolved to LEFT or RIGHT depending on RecyclerView's layout

* direction. Used for swipe & drag control.

*/

public static final int END = RIGHT << 2;

/**

* ItemTouchHelper is in idle state. At this state, either there is no related motion event by

* the user or latest motion events have not yet triggered a swipe or drag.

*/

public static final int ACTION_STATE_IDLE = 0;

/**

* A View is currently being swiped.

*/

public static final int ACTION_STATE_SWIPE = 1;

/**

* A View is currently being dragged.

*/

public static final int ACTION_STATE_DRAG = 2;

/**

* Animation type for views which are swiped successfully.

*/

public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 1 << 1;

/**

* Animation type for views which are not completely swiped thus will animate back to their

* original position.

*/

public static final int ANIMATION_TYPE_SWIPE_CANCEL = 1 << 2;

/**

* Animation type for views that were dragged and now will animate to their final position.

*/

public static final int ANIMATION_TYPE_DRAG = 1 << 3;

static final String TAG = "ItemTouchHelper";

static final boolean DEBUG = true;

static final int ACTIVE_POINTER_ID_NONE = -1;

static final int DIRECTION_FLAG_COUNT = 8;

private static final int ACTION_MODE_IDLE_MASK = (1 << DIRECTION_FLAG_COUNT) - 1;

static final int ACTION_MODE_SWIPE_MASK = ACTION_MODE_IDLE_MASK << DIRECTION_FLAG_COUNT;

static final int ACTION_MODE_DRAG_MASK = ACTION_MODE_SWIPE_MASK << DIRECTION_FLAG_COUNT;

/**

* The unit we are using to track velocity

*/

private static final int PIXELS_PER_SECOND = 1000;

/**

* Views, whose state should be cleared after they are detached from RecyclerView.

* This is necessary after swipe dismissing an item. We wait until animator finishes its job

* to clean these views.

*/

final List mPendingCleanup = new ArrayList();

/**

* Re-use array to calculate dx dy for a ViewHolder

*/

private final float[] mTmpPosition = new float[2];

/**

* Currently selected view holder

*/

ViewHolder mSelected = null;

/**

* The reference coordinates for the action start. For drag & drop, this is the time long

* press is completed vs for swipe, this is the initial touch point.

*/

float mInitialTouchX;

float mInitialTouchY;

/**

* Set when ItemTouchHelper is assigned to a RecyclerView.

*/

float mSwipeEscapeVelocity;

/**

* Set when ItemTouchHelper is assigned to a RecyclerView.

*/

float mMaxSwipeVelocity;

/**

* The diff between the last event and initial touch.

*/

float mDx;

float mDy;

/**

* The coordinates of the selected view at the time it is selected. We record these values

* when action starts so that we can consistently position it even if LayoutManager moves the

* View.

*/

float mSelectedStartX;

float mSelectedStartY;

/**

* The pointer we are tracking.

*/

int mActivePointerId = ACTIVE_POINTER_ID_NONE;

/**

* Developer callback which controls the behavior of ItemTouchHelper.

*/

Callback mCallback;

/**

* Current mode.

*/

int mActionState = ACTION_STATE_IDLE;

/**

* The direction flags obtained from unmasking

* {@link Callback#getAbsoluteMovementFlags(RecyclerView, ViewHolder)} for the current

* action state.

*/

int mSelectedFlags;

/**

* When a View is dragged or swiped and needs to go back to where it was, we create a Recover

* Animation and animate it to its location using this custom Animator, instead of using

* framework Animators.

* Using framework animators has the side effect of clashing with ItemAnimator, creating

* jumpy UIs.

*/

List mRecoverAnimations = new ArrayList();

private int mSlop;

RecyclerView mRecyclerView;

/**

* When user drags a view to the edge, we start scrolling the LayoutManager as long as View

* is partially out of bounds.

*/

final Runnable mScrollRunnable = new Runnable() {

@Override

public void run() {

if (mSelected != null && scrollIfNecessary()) {

if (mSelected != null) { //it might be lost during scrolling

moveIfNecessary(mSelected);

}

mRecyclerView.removeCallbacks(mScrollRunnable);

ViewCompat.postOnAnimation(mRecyclerView, this);

}

}

};

/**

* Used for detecting fling swipe

*/

VelocityTracker mVelocityTracker;

//re-used list for selecting a swap target

private List mSwapTargets;

//re used for for sorting swap targets

private List mDistances;

/**

* If drag & drop is supported, we use child drawing order to bring them to front.

*/

private RecyclerView.ChildDrawingOrderCallback mChildDrawingOrderCallback = null;

/**

* This keeps a reference to the child dragged by the user. Even after user stops dragging,

* until view reaches its final position (end of recover animation), we keep a reference so

* that it can be drawn above other children.

*/

View mOverdrawChild = null;

/**

* We cache the position of the overdraw child to avoid recalculating it each time child

* position callback is called. This value is invalidated whenever a child is attached or

* detached.

*/

int mOverdrawChildPosition = -1;

/**

* Used to detect long press.

*/

GestureDetectorCompat mGestureDetector;

private final OnItemTouchListener mOnItemTouchListener

= new OnItemTouchListener() {

@Override

public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {

mGestureDetector.onTouchEvent(event);

if (DEBUG) {

Log.d(TAG, "intercept: x:" + event.getX() + ",y:" + event.getY() + ", " + event);

}

final int action = MotionEventCompat.getActionMasked(event);

if (action == MotionEvent.ACTION_DOWN) {

mActivePointerId = event.getPointerId(0);

mInitialTouchX = event.getX();

mInitialTouchY = event.getY();

obtainVelocityTracker();

if (mSelected == null) {

final RecoverAnimation animation = findAnimation(event);

if (animation != null) {

mInitialTouchX -= animation.mX;

mInitialTouchY -= animation.mY;

endRecoverAnimation(animation.mViewHolder, true);

if (mPendingCleanup.remove(animation.mViewHolder.itemView)) {

mCallback.clearView(mRecyclerView, animation.mViewHolder);

}

select(animation.mViewHolder, animation.mActionState);

updateDxDy(event, mSelectedFlags, 0);

}

}

} else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

mActivePointerId = ACTIVE_POINTER_ID_NONE;

select(null, ACTION_STATE_IDLE);

} else if (mActivePointerId != ACTIVE_POINTER_ID_NONE) {

// in a non scroll orientation, if distance change is above threshold, we

// can select the item

final int index = event.findPointerIndex(mActivePointerId);

if (DEBUG) {

Log.d(TAG, "pointer index " + index);

}

if (index >= 0) {

checkSelectForSwipe(action, event, index);

}

}

if (mVelocityTracker != null) {

mVelocityTracker.addMovement(event);

}

return mSelected != null;

}

@Override

public void onTouchEvent<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值