下面列出了android.view.MotionEvent#ACTION_MOVE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
doDown(event);
break;
case MotionEvent.ACTION_MOVE:
doMove(event);
break;
case MotionEvent.ACTION_UP:
doUp(event);
break;
}
return true;
}
@SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(@NonNull MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (event.getX() < (scrollerView.getX() - scrollerView.getPaddingStart())) return false;
scrollerView.setSelected(true);
hideAppbar();
case MotionEvent.ACTION_MOVE:
float y = event.getY();
setScrollerHeight(y);
setRecyclerViewPosition(y);
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
scrollerView.setSelected(false);
showAppbar();
return true;
}
return super.onTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
handleActionDown(event);
break;
case MotionEvent.ACTION_MOVE:
handleActionMove(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
handleActionUp(event);
break;
}
} catch (Exception e) {
// 确保自己能被移除
removeSelfWithException();
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isSwipeEnabled()) return super.onTouchEvent(event);
int action = event.getActionMasked();
gestureDetector.onTouchEvent(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
mDragHelper.processTouchEvent(event);
sX = event.getRawX();
sY = event.getRawY();
case MotionEvent.ACTION_MOVE: {
//the drag state and the direction are already judged at onInterceptTouchEvent
checkCanDrag(event);
if (mIsBeingDragged) {
getParent().requestDisallowInterceptTouchEvent(true);
mDragHelper.processTouchEvent(event);
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
mDragHelper.processTouchEvent(event);
break;
default://handle other action, such as ACTION_POINTER_DOWN/UP
mDragHelper.processTouchEvent(event);
}
return super.onTouchEvent(event) || mIsBeingDragged || action == MotionEvent.ACTION_DOWN;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float y = event.getY();
float x = event.getX();
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
gotSlot = isInSelectedSlot(x, y);
downX = x;
downY = y;
break;
case MotionEvent.ACTION_MOVE:
if (gotSlot) {
if (x >= slotPositions[0] && x <= slotPositions[rangeCount - 1]) {
currentSlidingX = x;
currentSlidingY = y;
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
if (gotSlot) {
gotSlot = false;
currentSlidingX = x;
currentSlidingY = y;
updateCurrentIndex();
}
break;
}
return true;
}
/**
* Create a map represented touch event at a certain moment.
* @param motionEvent motionEvent, which contains all pointers event in a period of time
* @param pos index used to retrieve a certain moment in a period of time.
* @return touchEvent
* @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent">touchEvent</a>
*/
private Map<String, Object> createFireEventParam(MotionEvent motionEvent, int pos) {
JSONArray jsonArray = new JSONArray(motionEvent.getPointerCount());
if (motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
for (int i = 0; i < motionEvent.getPointerCount(); i++) {
jsonArray.add(createJSONObject(motionEvent, pos, i));
}
} else if (isPointerNumChanged(motionEvent)) {
int pointerIndex = motionEvent.getActionIndex();
jsonArray.add(createJSONObject(motionEvent, CUR_EVENT, pointerIndex));
}
Map<String, Object> map = new HashMap<>();
map.put(GestureInfo.HISTORICAL_XY, jsonArray);
return map;
}
@Override
public boolean onTouchEvent(final MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
mHistoricalTop = getChildAt(0).getTop();
break;
case MotionEvent.ACTION_UP:
if (!mIsRefreshing) {
if (mArrowUp) {
startRefreshing();
mHandler.sendMessage(mHandler.obtainMessage(REFRESH, (int) (ev.getY() - mY)
/ 2 + mInitialHeight, 0));
} else {
if (getChildAt(0).getTop() == 0) {
mHandler.sendMessage(mHandler.obtainMessage(NORMAL,
(int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
}
}
} else {
mHandler.sendMessage(mHandler.obtainMessage(REFRESH, (int) (ev.getY() - mY) / 2
+ mInitialHeight, 0));
}
mFlag = false;
break;
}
return super.onTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (status == DISABLE_STATUS) {
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
status = FOCUS_STATUS;
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
if (x < 0 || x > width || y > height || y < 0) {
status = NORMAL_STATUS;
}
break;
case MotionEvent.ACTION_CANCEL:
status = NORMAL_STATUS;
break;
case MotionEvent.ACTION_UP:
if (status != FOCUS_STATUS) {
return true;
}
status = PRESSED_STATUS;
objectAnimator = ObjectAnimator.ofFloat(this, "rotation", rotateDegree);
objectAnimator.setDuration(rotateTime);
objectAnimator.start();
if (rotateMode == REVERSE && rotateDegree != 0) {
rotateDegree -= degree;
if (listener != null) {
listener.onForward();
}
} else {
rotateDegree += degree;
if (listener != null) {
listener.onBack();
}
}
break;
}
invalidate();
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
mGestureDetector.onTouchEvent(event);
PointF curr = new PointF(event.getX(), event.getY());
if (state == State.NONE || state == State.DRAG || state == State.FLING) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(curr);
if (fling != null) {
fling.cancelFling();
}
setState(State.DRAG);
break;
case MotionEvent.ACTION_MOVE:
if (state == State.DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float fixTransX = getFixDragTrans(deltaX, viewWidth, getImageWidth());
float fixTransY = getFixDragTrans(deltaY, viewHeight, getImageHeight());
matrix.postTranslate(fixTransX, fixTransY);
fixTrans();
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
setState(State.NONE);
break;
}
}
setImageMatrix(matrix);
//
// User-defined OnTouchListener
//
if (userTouchListener != null) {
userTouchListener.onTouch(v, event);
}
//
// OnTouchImageViewListener is set: TouchImageView dragged by user.
//
if (touchImageViewListener != null) {
touchImageViewListener.onMove();
}
//
// indicate event was handled
//
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mOuterIsEnable) {
return super.onTouchEvent(event);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
currentMS = System.currentTimeMillis();
LogUtil.logD("201811161726", "MotionEvent.ACTION_DOWN->currentMS = " + currentMS);
break;
case MotionEvent.ACTION_MOVE:
LogUtil.logD("201811161726", "MotionEvent.ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
long moveTime = System.currentTimeMillis() - currentMS;
LogUtil.logD("201811161726", "moveTime = " + moveTime);
if (moveTime < 120) { // 点击判定条件
if (EmptyUtils.isNotEmpty(mOuterRfList)) {
RingVBean bean;
int size = mOuterRfList.size();
for (int i = 0; i < size; i++) {
bean = mOuterRfList.get(i);
LogUtil.logD("201812121815", "矩阵 = " + bean.getRf().toString() + "->downX = " + downX +
"->downY = " + downY + "->是否包含 = " + bean.isInChartArea(bean.getRf(), downX, downY) + "->size = " + size);
if (bean.isInChartArea(bean.getRf(), downX, downY)) {
if (mListener != null) {
mListener.onOuterClick(bean.getLabel());
}
break;
}
}
}
}
break;
default:
break;
}
return true;
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
inTapRegion = true;
mStartX = event.getX();
mStartY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
mCurrentX = event.getX();
mCurrentY = event.getY();
int dx = (int) (mCurrentX - mStartX);
int dy = (int) (mCurrentY - mStartY);
int distance = dx * dx + dy * dy;
if (distance > mTouchSlop) {
inTapRegion = false;
}
break;
case MotionEvent.ACTION_UP:
if (inTapRegion) {
int index;
if (mDirection == Direction.HORIZON) {
index = (int) (mStartX / mSingleChildWidth);
} else {
index = (int) (mStartY / mSingleChildHeight);
}
if (mCurrentIndex != index) {
if (mOnSegmentControlClickListener != null) {
mOnSegmentControlClickListener.onSegmentControlClick(index);
}
} else {
if (mOnSegmentControlClickListener != null) {
mOnSegmentControlClickListener.onSegmentControlReselect();
}
}
mCurrentIndex = index;
invalidate();
}
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float sumX = 0;
float sumY = 0;
boolean pointerUp = event.getActionMasked() == MotionEvent.ACTION_POINTER_UP;
int skippedPointer = pointerUp ? event.getActionIndex() : -1; // 计算焦点时跳过抬起的手指
int count = event.getPointerCount();
for (int i = 0; i < count; i++) {
if (skippedPointer != i) { // 跳过抬起的手指
sumX += event.getX(i);
sumY += event.getY(i);
}
}
int divisor = pointerUp ? count - 1 : count; // 如果是 ACTION_POINTER_UP 事件,除数减一
float focusX = sumX / divisor;
float focusY = sumY / divisor;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
downX = focusX;
downY = focusY;
oldOffsetX = offsetX;
oldOffsetY = offsetY;
break;
case MotionEvent.ACTION_POINTER_DOWN:
downX = focusX;
downY = focusY;
oldOffsetX = offsetX;
oldOffsetY = offsetY;
break;
case MotionEvent.ACTION_POINTER_UP:
downX = focusX;
downY = focusY;
oldOffsetX = offsetX;
oldOffsetY = offsetY;
break;
case MotionEvent.ACTION_MOVE:
float deltaX = focusX - downX;
float deltaY = focusY - downY;
offsetX = oldOffsetX + deltaX;
offsetY = oldOffsetY + deltaY;
invalidate();
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(mItemHeight == 0) return true;
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
currY = event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mFlagMayPress = true;
mHandlerInNewThread.removeMessages(HANDLER_WHAT_REFRESH);
stopScrolling();
downY = currY;
downYGlobal = mCurrDrawGlobalY;
onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
float spanY = downY - currY;
if(mFlagMayPress && (-mScaledTouchSlop < spanY && spanY < mScaledTouchSlop)){
}else{
mFlagMayPress = false;
mCurrDrawGlobalY = limitY((int)(downYGlobal + spanY));
calculateFirstItemParameterByGlobalY();
invalidate();
}
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
break;
case MotionEvent.ACTION_UP:
if(mFlagMayPress){
click(event);
}else {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityY = (int) (velocityTracker.getYVelocity() * mFriction);
if (Math.abs(velocityY) > mMiniVelocityFling) {
mScroller.fling(0, mCurrDrawGlobalY, 0, -velocityY,
Integer.MIN_VALUE, Integer.MAX_VALUE, limitY(Integer.MIN_VALUE), limitY(Integer.MAX_VALUE));
invalidate();
onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
}
mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), 0);
releaseVelocityTracker();
}
break;
case MotionEvent.ACTION_CANCEL:
downYGlobal = mCurrDrawGlobalY;
stopScrolling();
mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), 0);
break;
}
return true ;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
getParent().requestDisallowInterceptTouchEvent(true);
// Convert coordinates to our internal coordinate system
float x = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsMovingPointer = true;
// Check whether the user pressed on (or near) the pointer
if (x >= (mBarPointerHaloRadius)
&& x <= (mBarPointerHaloRadius + mBarLength)) {
mBarPointerPosition = Math.round(x);
calculateColor(Math.round(x));
mBarPointerPaint.setColor(mColor);
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsMovingPointer) {
// Move the the pointer on the bar.
if (x >= mBarPointerHaloRadius
&& x <= (mBarPointerHaloRadius + mBarLength)) {
mBarPointerPosition = Math.round(x);
calculateColor(Math.round(x));
mBarPointerPaint.setColor(mColor);
if (mPicker != null) {
mPicker.setNewCenterColor(mColor);
mPicker.changeOpacityBarColor(mColor);
}
invalidate();
} else if (x < mBarPointerHaloRadius) {
mBarPointerPosition = mBarPointerHaloRadius;
mColor = Color.HSVToColor(mHSVColor);
mBarPointerPaint.setColor(mColor);
if (mPicker != null) {
mPicker.setNewCenterColor(mColor);
mPicker.changeOpacityBarColor(mColor);
}
invalidate();
} else if (x > (mBarPointerHaloRadius + mBarLength)) {
mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
mColor = Color.BLACK;
mBarPointerPaint.setColor(mColor);
if (mPicker != null) {
mPicker.setNewCenterColor(mColor);
mPicker.changeOpacityBarColor(mColor);
}
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
mIsMovingPointer = false;
break;
}
return true;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
durTouchX = event.getX();
durTouchY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
if (durTouchX == -1000000) {
durTouchX = event.getX();
}
if (durTouchY == -1000000)
durTouchY = event.getY();
float dY = event.getY() - durTouchY; //>0下拉
durTouchY = event.getY();
if (baseRefreshListener != null && ((RefreshRecyclerViewAdapter) Objects.requireNonNull(recyclerView.getAdapter())).getIsRequesting() == 0 && rpb.getSecondDurProgress() == rpb.getSecondFinalProgress()) {
if (rpb.getVisibility() != View.VISIBLE) {
rpb.setVisibility(View.VISIBLE);
}
if (recyclerView.getAdapter().getItemCount() > 0) {
if (0 == ((LinearLayoutManager) Objects.requireNonNull(recyclerView.getLayoutManager())).findFirstCompletelyVisibleItemPosition()) {
rpb.setSecondDurProgress((int) (rpb.getSecondDurProgress() + dY));
}
} else {
rpb.setSecondDurProgress((int) (rpb.getSecondDurProgress() + dY));
}
return rpb.getSecondDurProgress() > 0;
}
break;
case MotionEvent.ACTION_UP:
if (baseRefreshListener != null && rpb.getSecondMaxProgress() > 0 && rpb.getSecondDurProgress() > 0) {
if (rpb.getSecondDurProgress() >= rpb.getSecondMaxProgress() && ((RefreshRecyclerViewAdapter) Objects.requireNonNull(recyclerView.getAdapter())).getIsRequesting() == 0) {
if (baseRefreshListener instanceof OnRefreshWithProgressListener) {
//带有进度的
//执行刷新响应
((RefreshRecyclerViewAdapter) recyclerView.getAdapter()).setIsAll(false, false);
((RefreshRecyclerViewAdapter) recyclerView.getAdapter()).setIsRequesting(1, true);
rpb.setMaxProgress(((OnRefreshWithProgressListener) baseRefreshListener).getMaxProgress());
baseRefreshListener.startRefresh();
if (noDataView != null) {
noDataView.setVisibility(GONE);
}
if (refreshErrorView != null) {
refreshErrorView.setVisibility(GONE);
}
} else {
//不带进度的
((RefreshRecyclerViewAdapter) recyclerView.getAdapter()).setIsAll(false, false);
((RefreshRecyclerViewAdapter) recyclerView.getAdapter()).setIsRequesting(1, true);
baseRefreshListener.startRefresh();
if (noDataView != null) {
noDataView.setVisibility(GONE);
}
if (refreshErrorView != null) {
refreshErrorView.setVisibility(GONE);
}
rpb.setIsAutoLoading(true);
}
} else {
if (((RefreshRecyclerViewAdapter) Objects.requireNonNull(recyclerView.getAdapter())).getIsRequesting() != 1)
rpb.setSecondDurProgressWithAnim(0);
}
}
durTouchX = -1000000;
durTouchY = -1000000;
break;
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
ensureTarget();
final int action = MotionEventCompat.getActionMasked(ev);
if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}
switch (mDirection) {
case BOTTOM:
if (!isEnabled() || mReturningToStart || (!mBothDirection && canChildScrollDown()) || mRefreshing) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
break;
case TOP:
default:
if (!isEnabled() || mReturningToStart || (!mBothDirection && canChildScrollUp()) || mRefreshing) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
break;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop(), true);
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mIsBeingDragged = false;
final float initialMotionY = getMotionEventY(ev, mActivePointerId);
if (initialMotionY == -1) {
return false;
}
mInitialMotionY = initialMotionY;
case MotionEvent.ACTION_MOVE:
if (mActivePointerId == INVALID_POINTER) {
return false;
}
final float y = getMotionEventY(ev, mActivePointerId);
if (y == -1) {
return false;
}
if (mBothDirection) {
if (y > mInitialMotionY) {
setRawDirection(SwipyRefreshLayoutDirection.TOP);
} else if (y < mInitialMotionY) {
setRawDirection(SwipyRefreshLayoutDirection.BOTTOM);
}
if ((mDirection == SwipyRefreshLayoutDirection.BOTTOM && canChildScrollDown())
|| (mDirection == SwipyRefreshLayoutDirection.TOP && canChildScrollUp())) {
return false;
}
}
float yDiff;
switch (mDirection) {
case BOTTOM:
yDiff = mInitialMotionY - y;
break;
case TOP:
default:
yDiff = y - mInitialMotionY;
break;
}
if (yDiff > mTouchSlop && !mIsBeingDragged) {
mIsBeingDragged = true;
mProgress.setAlpha(STARTING_PROGRESS_ALPHA);
}
break;
case MotionEventCompat.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
break;
}
return mIsBeingDragged;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
if (!scrollable) {
return false;
}
if (mTouchTopOutSide || mIsFling) {
return true;
}
float currentY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = currentY;
return true;
case MotionEvent.ACTION_MOVE: {
if (!mDragStart) {
mDragStart = true;
callback.onDragStart();
}
float dy = currentY - lastY;
lastY = currentY;
boolean doSwipeClose = false;
// case 1 : 正常拖动數值
float newTransY = childView.getTranslationY() + dy;
// case 2 : 低于最小可移动高度Y
if (newTransY < minTransY) {
newTransY = minTransY;
}
// case 3 : 达到上限位置以后可以继续向上运动,运动距离衰减为手指移动距离的1/2
else if (newTransY < stateHighTranslationY) {
newTransY = childView.getTranslationY() + dy / 2;
}
// case 4 : 超过键盘底端 最多设置为底端
else if (newTransY >= getMeasuredHeight()) {
newTransY = getMeasuredHeight();
doSwipeClose = true;
}
childView.setTranslationY(newTransY);
callback.onTranslationYChanged(newTransY);
// 超过键盘底端 关闭
if (doSwipeClose && callback != null) {
callback.onSwipeClose();
}
return true;
}
case MotionEvent.ACTION_UP:
mDragStart = false;
lastY = currentY;
// 在键盘工具列下方
if (childView.getTranslationY() > stateLowTranslationY) {
int closeBoundary = stateLowTranslationY + (getMeasuredHeight() - stateLowTranslationY) / 2;
// 在键盘工具列下方空间一半以上 回到工具列高度 反之关闭
boolean needClose = childView.getTranslationY() > closeBoundary;
animateTo(needClose ? STATE_CLOSE : STATE_LOW, ANIMATION_DURATION_150, null);
}
// 在键盘工具列上方
else {
// 需要缓冲值让他返回最高高度 (ex : Touch Event很难刚好把Y移动到0)
if (childView.getTranslationY() < stateHighTranslationY + MOVE_HIGH_TRANSLATION_Y_DIFFERENCE) {
animateTo(STATE_HIGH, ANIMATION_DURATION_150, null);
} else {
// 直接停放
setState(STATE_MIDDLE);
}
}
return true;
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!allowDrag)
return false;
ensureTarget();
final int action = MotionEventCompat.getActionMasked(ev);
/*if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}*/
final boolean isTop = !canChildScrollUp();
final boolean isBottom = !canChildScrollDown();
if (!isEnabled() || mReturningToStart || (!isTop && !isBottom) || tRefreshing || bRefreshing) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
if (!bOriginalOffsetCalculated) {
bCurrentTargetOffsetTop = bOriginalOffsetTop = getMeasuredHeight();
bOriginalOffsetCalculated = true;
Log.e(TAG, "onLayout>>set bOriginalOffsetTop=" + bOriginalOffsetTop);
}
tIsBeingDragged = false;
bIsBeingDragged = false;
if (isBottom) {
setTargetOffsetTopAndBottom(bCircleView, bOriginalOffsetTop - bCircleView.getTop(), true);
} else
return false;
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
final float initialDownY = getMotionEventY(ev, mActivePointerId);
if (initialDownY == -1) {
return false;
}
mInitialDownY = initialDownY;
break;
case MotionEvent.ACTION_MOVE:
if (mActivePointerId == INVALID_POINTER) {
android.util.Log.e(LOG_TAG, "Got ACTION_MOVE event but don't have an active pointer id.");
return false;
}
final float y = getMotionEventY(ev, mActivePointerId);
if (y == -1) {
return false;
}
final float yDiff = y - mInitialDownY;
if (isBottom && yDiff < 0 && Math.abs(yDiff) > mTouchSlop && !bIsBeingDragged) {
mInitialMotionY = mInitialDownY - mTouchSlop;
bIsBeingDragged = true;
bProgress.setAlpha(STARTING_PROGRESS_ALPHA);
}
break;
case MotionEventCompat.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
tIsBeingDragged = false;
bIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
break;
}
return tIsBeingDragged || bIsBeingDragged;
}
private void onTouchDragEvent(int action, MotionEvent ev) {
switch (action) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY;
if (!mIsDragging) {
mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mScaleDragGestureListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker.getYVelocity();
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mScaleDragGestureListener.onFling(mLastTouchX, mLastTouchY, -vX, -vY);
}
}
}
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
}