下面列出了android.view.MotionEvent#ACTION_UP 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onSideBarTouch(View v, MotionEvent event, int touchPosition) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
showCenterOverlayView(mSideBar.getIndexValue(touchPosition));
if(touchPosition != mSideBar.getSelectPosition()) {
if(touchPosition == 0) {
mLinearLayoutManager.scrollToPosition(0);
} else {
int recyclerViewPosition = getScrollPositionBySideBarSelectPosition(touchPosition);
mLinearLayoutManager.scrollToPositionWithOffset(recyclerViewPosition, 0);
}
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
hideCenterOverlayView();
break;
}
}
@Override
public void onTouchEvent(@NonNull RecyclerView recyclerView, @NonNull MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
hoverMode = false;
popup.dismiss();
eventListener.onStickerPopupEnded();
break;
default:
for (int i = 0, len = recyclerView.getChildCount(); i < len; i++) {
View child = recyclerView.getChildAt(i);
if (ViewUtil.isPointInsideView(recyclerView, motionEvent.getRawX(), motionEvent.getRawY()) &&
ViewUtil.isPointInsideView(child, motionEvent.getRawX(), motionEvent.getRawY()))
{
showStickerForView(recyclerView, child);
}
}
}
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
switch (e.getAction()){
case MotionEvent.ACTION_DOWN:
Log.i("--->", "ACTION_DOWN");
break;
case MotionEvent.ACTION_UP: //双指点击时不会触发
Log.i("--->", "ACTION_UP");
if (isClosePress) {
//代处理其它事件
} else {
isClosePress = true;
}
break;
case MotionEvent.ACTION_MOVE:
Log.i("--->", "ACTION_MOVE");
break;
}
return false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
// 设置开始点位置
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
try {
boolean result = super.onTouchEvent(widget, buffer, event);
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
Selection.removeSelection(buffer);
}
return result;
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_POINTER_UP:
// Ignore deprecation, ACTION_POINTER_ID_MASK and
// ACTION_POINTER_ID_SHIFT has same value and are deprecated
// You can have either deprecation or lint target api warning
final int pointerIndex = Compat.getPointerIndex(ev.getAction());
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
}
break;
}
mActivePointerIndex = ev
.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
: 0);
return super.onTouchEvent(ev);
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
try {
boolean result = super.onTouchEvent(widget, buffer, event);
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
Selection.removeSelection(buffer);
}
return result;
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchX = event.getX() + getLeft();
touchY = event.getY() + getTop();
startX = event.getRawX();
startY = event.getRawY();
isDragging = false;
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) (event.getRawX() - startX);
int dy = (int) (event.getRawY() - startY);
if ((dx * dx + dy * dy) > mTouchSlop) {
isDragging = true;
mLp.x = (int) (event.getRawX() - touchX);
mLp.y = (int) (event.getRawY() - touchY);
mWm.updateViewLayout(FloatView.this, mLp);
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
touchX = touchY = 0.0F;
if (isDragging) {
reposition();
isDragging = false;
return true;
}
}
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
removeAllCallbacks();
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
final int actionMasked = motionEvent.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
if (view instanceof ViewGroup) {
mInitialTouchTarget = findNearestChild((ViewGroup) view,
(int) motionEvent.getX(), (int) motionEvent.getY());
} else {
mInitialTouchTarget = null;
}
}
final View child = mInitialTouchTarget;
if (child == null) {
return false;
}
final float offsetX = view.getScrollX() - child.getLeft();
final float offsetY = view.getScrollY() - child.getTop();
motionEvent.offsetLocation(offsetX, offsetY);
final boolean handled = child.dispatchTouchEvent(motionEvent);
motionEvent.offsetLocation(-offsetX, -offsetY);
if (actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_CANCEL) {
mInitialTouchTarget = null;
}
return handled;
}
/**
* Handles the SDL Touch Event to keep track of pointer status and returns the appropriate
* Android MotionEvent according to this events status
* @param touchType The SDL TouchType that was received from the module
* @param touchEvent The SDL TouchEvent that was received from the module
* @return the correct native Android MotionEvent action to dispatch
*/
synchronized int getMotionEventAction(TouchType touchType, TouchEvent touchEvent){
eventTime = 0;
int motionEventAction = -1;
switch (touchType){
case BEGIN:
if(pointers.size() == 0){
//The motion event has just begun
motionEventAction = MotionEvent.ACTION_DOWN;
downTime = SystemClock.uptimeMillis();
downTimeOnHMI = touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1);
eventTime = downTime;
} else{
motionEventAction = MotionEvent.ACTION_POINTER_DOWN | pointers.size() << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
}
pointers.add(new Pointer(touchEvent.getId()));
break;
case MOVE:
motionEventAction = MotionEvent.ACTION_MOVE;
eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
break;
case END:
if(pointers.size() <= 1){
//The motion event has just ended
motionEventAction = MotionEvent.ACTION_UP;
} else {
int pointerIndex = pointers.indexOf(getPointerById(touchEvent.getId()));
if (pointerIndex != -1) {
motionEventAction = MotionEvent.ACTION_POINTER_UP | pointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
} else {
motionEventAction = MotionEvent.ACTION_UP;
}
}
eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
break;
case CANCEL:
//Assuming this cancels the entire event
motionEventAction = MotionEvent.ACTION_CANCEL;
eventTime = downTime + touchEvent.getTimestamps().get(touchEvent.getTimestamps().size() - 1) - downTimeOnHMI;
break;
default:
break;
}
return motionEventAction;
}
/**
* 处理我们拖动ListView item的逻辑
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isSlide && slidePosition != AdapterView.INVALID_POSITION) {
requestDisallowInterceptTouchEvent(true);
addVelocityTracker(ev);
final int action = ev.getAction();
int x = (int) ev.getX();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
MotionEvent cancelEvent = MotionEvent.obtain(ev);
cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
(ev.getActionIndex()<< MotionEvent.ACTION_POINTER_INDEX_SHIFT));
onTouchEvent(cancelEvent);
int deltaX = downX - x;
downX = x;
// 手指拖动itemView滚动, deltaX大于0向左滚动,小于0向右滚
itemView.scrollBy(deltaX, 0);
return true; //拖动的时候ListView不滚动
case MotionEvent.ACTION_UP:
int velocityX = getScrollVelocity();
if (velocityX > SNAP_VELOCITY) {
scrollRight();
} else if (velocityX < -SNAP_VELOCITY) {
scrollLeft();
} else {
scrollByDistanceX();
}
recycleVelocityTracker();
// 手指离开的时候就不响应左右滚动
isSlide = false;
break;
}
}
//否则直接交给ListView来处理onTouchEvent事件
return super.onTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
} else {
Log.i(LOG_TAG, "Velocity tracker is null");
}
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) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
// Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
.getYVelocity();
// If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX,
-vY);
}
}
}
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
return true;
}
@Override
public final boolean onTouchEvent(MotionEvent event) {
if (!isPullToRefreshEnabled()) {
return false;
}
// If we're refreshing, and the flag is set. Eat the event
if (!mScrollingWhileRefreshingEnabled && isRefreshing()) {
return true;
}
if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
if (mIsBeingDragged) {
mLastMotionY = event.getY();
mLastMotionX = event.getX();
pullEvent();
return true;
}
break;
}
case MotionEvent.ACTION_DOWN: {
if (isReadyForPull()) {
mLastMotionY = mInitialMotionY = event.getY();
mLastMotionX = mInitialMotionX = event.getX();
return true;
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
if (mIsBeingDragged) {
mIsBeingDragged = false;
if (mState == State.RELEASE_TO_REFRESH
&& (null != mOnRefreshListener || null != mOnRefreshListener2)) {
setState(State.REFRESHING, true);
return true;
}
// If we're already refreshing, just scroll back to the top
if (isRefreshing()) {
smoothScrollTo(0);
return true;
}
// If we haven't returned by here, then we're not in a state
// to pull, so just reset
setState(State.RESET);
return true;
}
break;
}
}
return false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
/** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指压下屏幕
case MotionEvent.ACTION_DOWN:
mode = MODE_ZOOM;
startDis = event.getY();
// Log.i("Test", "ACTION_DOWN");
// int leftMargin = (width / 2) + cX + MAX_FRAME_WIDTH/2-(int)(25*density);
int leftMargin = cX / 2 + MAX_FRAME_WIDTH / 2 - (int) (25 * density);
int topMargin = cY / 2 - (int) (25 * density);
/**
* 显示seekbar
*/
// popupWindow.showAtLocation(v, Gravity.CENTER, leftMargin,topMargin);
break;
/* case MotionEvent.ACTION_POINTER_DOWN:
//如果mZoomSeekBar为null 表示该设备不支持缩放 直接跳过设置mode Move指令也无法执行
if (seekbar == null) return true;
//移除token对象为mZoomSeekBar的延时任务
mHandler.removeCallbacksAndMessages(seekbar);
seekbar.setVisibility(View.VISIBLE);
mode = MODE_ZOOM;
*//** 计算两个手指间的距离 *//*
startDis = distance(event);
break;*/
case MotionEvent.ACTION_MOVE:
/**
* 控制设置zoom没16毫秒触发,不到时间不触发
*/
if (mode == MODE_ZOOM) {
/* //只有同时触屏两个点的时候才执行
if(event.getPointerCount()<2) return true;*/
float endDis = startDis - event.getY();// 结束距离
int scale = (int) (endDis / (ScreenHeight / getMaxZoom()));
if (scale == 0 && endDis < 0) {
scale = -1;
} else if (scale == 0 && endDis > 0) {
scale = 1;
}
// Log.i("Test", "scale:" + scale);
/**
* 处理时间
*/
long endTime = System.currentTimeMillis();
long time = endTime - beginTime;
beginTime = System.currentTimeMillis();
if (scale >= 1 || scale <= -1) {
int zoom = getZoom() + scale;
//zoom不能超出范围
if (zoom > getMaxZoom()) zoom = getMaxZoom();
if (zoom < 0) zoom = 0;
// Log.i("Test", "zoom:" + zoom + ",Time:" + time);
setZoom(zoom);
// progressBar.setProgress(zoom);
//将最后一次的距离设为当前距离
// startDis = endDis;
}
}
break;
// 手指离开屏幕
case MotionEvent.ACTION_UP:
/*if(mode!=MODE_ZOOM){
//设置聚焦
Point point=new Point((int)event.getX(), (int)event.getY());
mCameraView.onFocus(point,autoFocusCallback);
mFocusImageView.startFocus(point);
}else {*/
//ZOOM模式下 在结束两秒后隐藏seekbar 设置token为mZoomSeekBar用以在连续点击时移除前一个定时任务
/*mHandler.postAtTime(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if(popupWindow.isShowing()){
popupWindow.dismiss();
}
}
}, progressBar,SystemClock.uptimeMillis()+5000);
// }*/
break;
}
return true;
}
void onTouchEvent(MotionEvent e) {
final int action = e.getActionMasked();
final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
final int skipIndex = pointerUp ? e.getActionIndex() : -1;
float sumX = 0, sumY = 0;
final int count = e.getPointerCount();
for (int i = 0; i < count; i++) {
if (skipIndex == i) continue;
sumX += e.getX(i);
sumY += e.getY(i);
}
final int div = pointerUp ? count - 1 : count;
final float focusX = sumX / div;
final float focusY = sumY / div;
if (count > 1 && !pointerUp) {
inRightClick = true;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
downFocusX = focusX;
downFocusY = focusY;
alwaysInTapRegion = true;
break;
case MotionEvent.ACTION_MOVE:
{
if (alwaysInTapRegion) {
final int deltaX = (int) (focusX - downFocusX);
final int deltaY = (int) (focusY - downFocusY);
int distance = (deltaX * deltaX) + (deltaY * deltaY);
if (distance > slopSquare) {
alwaysInTapRegion = false;
}
}
if (inRightClick && !alwaysInTapRegion && count > 1) {
gestureListener.onScroll((lastY - focusY) / 10.0f);
} else {
gestureListener.onMove(focusX - lastX, focusY - lastY);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (alwaysInTapRegion) {
press();
}
break;
case MotionEvent.ACTION_UP:
if (inRightClick) {
release();
} else if (alwaysInTapRegion && !inDoubleTap) {
press();
}
break;
default:
break;
}
lastX = focusX;
lastY = focusY;
gestureDetector.onTouchEvent(e);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mGestureDetector.onTouchEvent(event))
return true;
// if rotation by touch is enabled
if (mChart.isRotationEnabled()) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
stopDeceleration();
resetVelocity();
if (mChart.isDragDecelerationEnabled())
sampleVelocity(x, y);
setGestureStartAngle(x, y);
mTouchStartPoint.x = x;
mTouchStartPoint.y = y;
break;
case MotionEvent.ACTION_MOVE:
if (mChart.isDragDecelerationEnabled())
sampleVelocity(x, y);
if (mTouchMode == NONE
&& distance(x, mTouchStartPoint.x, y, mTouchStartPoint.y)
> Utils.convertDpToPixel(8f)) {
mTouchMode = ROTATE;
mChart.disableScroll();
} else if (mTouchMode == ROTATE) {
updateGestureRotation(x, y);
mChart.invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (mChart.isDragDecelerationEnabled()) {
stopDeceleration();
sampleVelocity(x, y);
mDecelerationAngularVelocity = calculateVelocity();
if (mDecelerationAngularVelocity != 0.f) {
mDecelerationLastTime = AnimationUtils.currentAnimationTimeMillis();
Utils.postInvalidateOnAnimation(mChart); // This causes computeScroll to fire, recommended for this by Google
}
}
mChart.enableScroll();
mTouchMode = NONE;
break;
}
}
return true;
}
public boolean applyTouchEvent(@NonNull MotionEvent motionEvent) {
if (!isShowing()) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
lastSeenDownPoint.set(motionEvent.getX(), motionEvent.getY());
}
return false;
}
if ((motionEvent.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) != 0) {
return true;
}
if (overlayState == OverlayState.UNINITAILIZED) {
downIsOurs = false;
deadzoneTouchPoint.set(motionEvent.getX(), motionEvent.getY());
overlayState = OverlayState.DEADZONE;
}
if (overlayState == OverlayState.DEADZONE) {
float deltaX = Math.abs(deadzoneTouchPoint.x - motionEvent.getX());
float deltaY = Math.abs(deadzoneTouchPoint.y - motionEvent.getY());
if (deltaX > touchDownDeadZoneSize || deltaY > touchDownDeadZoneSize) {
overlayState = OverlayState.SCRUB;
} else {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
overlayState = OverlayState.TAP;
if (downIsOurs) {
handleUpEvent();
return true;
}
}
return MotionEvent.ACTION_MOVE == motionEvent.getAction();
}
}
if (isToolbarTouch) {
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL || motionEvent.getAction() == MotionEvent.ACTION_UP) {
isToolbarTouch = false;
}
return false;
}
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
selected = getSelectedIndexViaDownEvent(motionEvent);
if (selected == -1) {
if (motionEvent.getRawY() < toolbar.getHeight() + statusBarHeight) {
isToolbarTouch = true;
return false;
}
}
deadzoneTouchPoint.set(motionEvent.getX(), motionEvent.getY());
overlayState = OverlayState.DEADZONE;
downIsOurs = true;
return true;
case MotionEvent.ACTION_MOVE:
selected = getSelectedIndexViaMoveEvent(motionEvent);
return true;
case MotionEvent.ACTION_UP:
handleUpEvent();
return downIsOurs;
case MotionEvent.ACTION_CANCEL:
hide();
return downIsOurs;
default:
return false;
}
}
@Override
public boolean dispatchTouchEvent(@SuppressWarnings("NullableProblems") MotionEvent event) {
if (mSelfUpdateScroll) {
mIsTouchOngoing = false;
mIsDraggingDraggable = false;
mIsScrolling = false;
mIsFlinging = false;
mOverScrollStarted = false;
removeCallbacks(mIdleRunnable);
removeCallbacks(mScrollRunnable);
return super.dispatchTouchEvent(event);
}
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
mIsTouchOngoing = true;
mScroller.abortAnimation();
if (mDraggableView != null && mDraggableView.getGlobalVisibleRect(mDraggableRect)) {
final int x = (int) (event.getRawX() + .5F);
final int y = (int) (event.getRawY() + .5F);
mIsDraggingDraggable = mDraggableRect.contains(x, y);
} else {
mIsDraggingDraggable = false;
}
} else if (action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_CANCEL){
mIsTouchOngoing = false;
if (mCloseUpAlgorithm != null) {
removeCallbacks(mIdleRunnable);
postDelayed(mIdleRunnable, mConsiderIdleMillis);
}
// great, now we are able to cancel ghost touch when up event Y == mMaxScrollY
if (mEventRedirected) {
if (action == MotionEvent.ACTION_UP) {
final float diff = Math.abs(event.getRawY() - mEventRedirectStartedY);
if (Float.compare(diff, mScaledTouchSlop) < 0) {
event.setAction(MotionEvent.ACTION_CANCEL);
}
}
mEventRedirected = false;
}
cancelOverScroll();
}
final boolean isPrevScrolling = mIsScrolling;
final boolean isPrevFlinging = mIsFlinging;
mIsFlinging = mFlingDetector .onTouchEvent(event);
mIsScrolling = mScrollDetector.onTouchEvent(event);
removeCallbacks(mScrollRunnable);
post(mScrollRunnable);
final boolean isIntercepted = mIsScrolling || mIsFlinging;
final boolean isPrevIntercepted = isPrevScrolling || isPrevFlinging;
final boolean shouldRedirectDownTouch = action == MotionEvent.ACTION_MOVE
&& (!isIntercepted && isPrevIntercepted)
&& getScrollY() == mMaxScrollY;
if (isIntercepted || isPrevIntercepted) {
mMotionEventHook.hook(event, MotionEvent.ACTION_CANCEL);
if (!isPrevIntercepted) {
return true;
}
}
if (shouldRedirectDownTouch) {
mMotionEventHook.hook(event, MotionEvent.ACTION_DOWN);
mEventRedirectStartedY = event.getRawY();
mEventRedirected = true;
}
super.dispatchTouchEvent(event);
return true;
}
@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;
}