下面列出了android.view.MotionEvent#getDownTime ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* check user double tapped this view.. or not.
* @param ev current motion event in a @{link MotionEvent}
* @return {@code true} if user double tapped this view.
*/
protected boolean isDoubleTap(MotionEvent ev){
//if old pointer is tapped?
if( ev.getPointerCount() > 1){
//if there are more than one pointer... reset
mLastTocuhDownTime = 0;
return false;
}
long downTime = ev.getDownTime();
long diff = downTime - mLastTocuhDownTime;
mLastTocuhDownTime = downTime;
return diff < DOUBLE_TAP_MARGIN_TIME;
}
private boolean handleMotionEvent(MotionEvent event) {
if (!mAttached) {
mQueuedEvents.add(new Pair(EVENT_SOURCE_MOTION, event));
return false;
}
if (event.getPointerCount() <= 0) {
return false;
}
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
mLastDownTime = event.getDownTime();
} else if (mLastDownTime != event.getDownTime()) {
return false;
}
final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
event.getPointerCoords(0, coords);
if (action == MotionEvent.ACTION_UP) {
mSession.click((int) coords.x, (int) coords.y);
}
return true;
}
@Override
public boolean onTouch(View view, MotionEvent e) {
if (getNavVisibility() && e.getAction() == MotionEvent.ACTION_UP && downTime != e.getDownTime()) {
toggleNavVisibility(); // this also removes navHider callbacks.
} else if (!getNavVisibility() && e.getAction() == MotionEvent.ACTION_DOWN) {
downTime = e.getDownTime();
toggleNavVisibility(); // this also removes navHider callbacks.
if (videoFragment != null && videoFragment.isPlaying()) {
handler.postDelayed(navHider, NAV_HIDE_DELAY);
}
}
return false;
}
void cancelLongPressIfNeeded(Iterator<MotionEvent> pendingEvents) {
if (mCurrentDownEvent == null)
return;
long currentDownTime = mCurrentDownEvent.getDownTime();
while (pendingEvents.hasNext()) {
MotionEvent pending = pendingEvents.next();
if (pending.getDownTime() != currentDownTime) {
break;
}
cancelLongPressIfNeeded(pending);
}
}
private MotionEvent transformEvent(MotionEvent e, int headerPosition) {
if (headerPosition == MATCHED_STICKIED_HEADER) {
return e;
}
long downTime = e.getDownTime();
long eventTime = e.getEventTime();
int action = e.getAction();
int pointerCount = e.getPointerCount();
int[] pointerIds = getPointerIds(e);
MotionEvent.PointerCoords[] pointerCoords = getPointerCoords(e);
int metaState = e.getMetaState();
float xPrecision = e.getXPrecision();
float yPrecision = e.getYPrecision();
int deviceId = e.getDeviceId();
int edgeFlags = e.getEdgeFlags();
int source = e.getSource();
int flags = e.getFlags();
View headerHolder = getChildAt(headerPosition);
for (int i = 0; i < pointerCount;i++) {
pointerCoords[i].y -= headerHolder.getTop();
}
MotionEvent n = MotionEvent.obtain(downTime, eventTime, action,
pointerCount, pointerIds, pointerCoords, metaState, xPrecision,
yPrecision, deviceId, edgeFlags, source, flags);
return n;
}
@Override
public void perform(UiController uiController, View view) {
float[] precision = precisionDescriber.describePrecision();
float[] start = this.start.calculateCoordinates(view);
float[] end = this.end.calculateCoordinates(view);
float[][] steps = interpolate(start, end, STEPS);
int delayBetweenMovements = DURATION / steps.length;
// Down
MotionEvent downEvent = MotionEvents.sendDown(uiController, start, precision).down;
try {
for (int i = 0; i < steps.length; i++) {
// Wait
long desiredTime = downEvent.getDownTime() + (long) (delayBetweenMovements * i);
long timeUntilDesired = desiredTime - SystemClock.uptimeMillis();
if (timeUntilDesired > 10L) {
uiController.loopMainThreadForAtLeast(timeUntilDesired);
}
// Move
if (!MotionEvents.sendMovement(uiController, downEvent, steps[i])) {
MotionEvents.sendCancel(uiController, downEvent);
throw new RuntimeException("Cannot drag: failed to send a move event.");
}
}
int duration = ViewConfiguration.getPressedStateDuration();
if (duration > 0) {
uiController.loopMainThreadForAtLeast((long) duration);
}
} finally {
downEvent.recycle();
}
}
private MotionEvent transformEvent(MotionEvent e, int headerPosition) {
if (headerPosition == MATCHED_STICKIED_HEADER) {
return e;
}
long downTime = e.getDownTime();
long eventTime = e.getEventTime();
int action = e.getAction();
int pointerCount = e.getPointerCount();
int[] pointerIds = getPointerIds(e);
MotionEvent.PointerCoords[] pointerCoords = getPointerCoords(e);
int metaState = e.getMetaState();
float xPrecision = e.getXPrecision();
float yPrecision = e.getYPrecision();
int deviceId = e.getDeviceId();
int edgeFlags = e.getEdgeFlags();
int source = e.getSource();
int flags = e.getFlags();
View headerHolder = getChildAt(headerPosition);
for (int i = 0; i < pointerCount;i++) {
pointerCoords[i].y -= headerHolder.getTop();
}
MotionEvent n = MotionEvent.obtain(downTime, eventTime, action,
pointerCount, pointerIds, pointerCoords, metaState, xPrecision,
yPrecision, deviceId, edgeFlags, source, flags);
return n;
}
static boolean isClickEvent(float startX, float startY, MotionEvent event) {
float duration = event.getEventTime() - event.getDownTime();
if (duration > MAX_CLICK_DURATION) {
return false;
}
float differenceX = Math.abs(startX - event.getX());
float differenceY = Math.abs(startY - event.getY());
return !(differenceX > MAX_CLICK_DISTANCE || differenceY > MAX_CLICK_DISTANCE);
}
private MotionEvent transformEvent(MotionEvent e, int headerPosition) {
if (headerPosition == MATCHED_STICKIED_HEADER) {
return e;
}
long downTime = e.getDownTime();
long eventTime = e.getEventTime();
int action = e.getAction();
int pointerCount = e.getPointerCount();
int[] pointerIds = getPointerIds(e);
MotionEvent.PointerCoords[] pointerCoords = getPointerCoords(e);
int metaState = e.getMetaState();
float xPrecision = e.getXPrecision();
float yPrecision = e.getYPrecision();
int deviceId = e.getDeviceId();
int edgeFlags = e.getEdgeFlags();
int source = e.getSource();
int flags = e.getFlags();
View headerHolder = getChildAt(headerPosition);
for (int i = 0; i < pointerCount;i++) {
pointerCoords[i].y -= headerHolder.getTop();
}
MotionEvent n = MotionEvent.obtain(downTime, eventTime, action,
pointerCount, pointerIds, pointerCoords, metaState, xPrecision,
yPrecision, deviceId, edgeFlags, source, flags);
return n;
}
/**
* Converts a hover {@link MotionEvent} to touch event by changing its
* action and source. Returns an modified clone of the original event.
* <p>
* The following types are affected:
* <ul>
* <li>{@link MotionEventCompatUtils#ACTION_HOVER_ENTER}
* <li>{@link MotionEventCompatUtils#ACTION_HOVER_MOVE}
* <li>{@link MotionEventCompatUtils#ACTION_HOVER_EXIT}
* </ul>
*
* @param hoverEvent The hover event to convert.
* @return a touch event
*/
public static MotionEvent convertHoverToTouch(MotionEvent hoverEvent) {
final MotionEvent touchEvent = MotionEvent.obtain(hoverEvent);
long downTime = sPreviousDownTime;
switch (touchEvent.getAction()) {
case MotionEventCompatUtils.ACTION_HOVER_ENTER:
touchEvent.setAction(MotionEvent.ACTION_DOWN);
sPreviousDownTime = SystemClock.uptimeMillis();
downTime = sPreviousDownTime;
break;
case MotionEventCompatUtils.ACTION_HOVER_MOVE:
touchEvent.setAction(MotionEvent.ACTION_MOVE);
break;
case MotionEventCompatUtils.ACTION_HOVER_EXIT:
touchEvent.setAction(MotionEvent.ACTION_UP);
sPreviousDownTime = 0;
break;
default:
downTime = touchEvent.getDownTime();
}
MotionEventCompatUtils.setSource(touchEvent, InputDeviceCompatUtils.SOURCE_MOUSE);
MotionEventCompatUtils.setDownTime(touchEvent, downTime);
return touchEvent;
}
void cancelLongPressIfNeeded(MotionEvent ev) {
if (!hasPendingMessage() ||
mCurrentDownEvent == null || ev.getDownTime() != mCurrentDownEvent.getDownTime()) {
return;
}
final int action = ev.getAction();
final float y = ev.getY();
final float x = ev.getX();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
final int deltaX = (int) (x - mCurrentDownEvent.getX());
final int deltaY = (int) (y - mCurrentDownEvent.getY());
int distance = (deltaX * deltaX) + (deltaY * deltaY);
if (distance > mTouchSlopSquare) {
cancelLongPress();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (calculateLongPressTimeoutTime(mCurrentDownEvent) > ev.getEventTime()) {
cancelLongPress();
}
break;
default:
break;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.isClickable()) {
/* handle press states */
if (event.getAction() == MotionEvent.ACTION_DOWN) {
v.setPressed(true);
timer = new Timer();
// Initial delay = length of a long press
timer.schedule(new IncrementTask(0, ViewConfiguration.getLongPressTimeout()), ViewConfiguration.getLongPressTimeout());
} else if (event.getAction() == MotionEvent.ACTION_UP) {
timer.cancel();
v.setPressed(false);
}
long lengthOfPress = event.getEventTime() - event.getDownTime();
// If the button has been "tapped" then handle normally
if (lengthOfPress < ViewConfiguration.getLongPressTimeout()
&& event.getAction() == MotionEvent.ACTION_UP) {
incrementListener.increment();
}
return true;
} else {
/* If the view isn't clickable, let the touch be handled by others. */
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled() || !isClickable()) {
return false;
}
int action = event.getAction();
float deltaX = event.getX() - mStartX;
float deltaY = event.getY() - mStartY;
// status the view going to change to when finger released
boolean nextStatus;
switch (action) {
case MotionEvent.ACTION_DOWN:
catchView();
mStartX = event.getX();
mStartY = event.getY();
mLastX = mStartX;
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
setProcess(getProcess() + (x - mLastX) / mSafeRectF.width());
mLastX = x;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setPressed(false);
nextStatus = getStatusBasedOnPos();
float time = event.getEventTime() - event.getDownTime();
if (deltaX < mTouchSlop && deltaY < mTouchSlop && time < mClickTimeout) {
performClick();
} else {
if (nextStatus != isChecked()) {
playSoundEffect(SoundEffectConstants.CLICK);
setChecked(nextStatus);
} else {
animateToState(nextStatus);
}
}
break;
default:
break;
}
return true;
}
public boolean onTouchEvent(View v, MotionEvent event) {
int distance = UIUtils.dp2px(1) * MIN_DISTANCE_MOVE;
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mStartX = x;
mStartY = y;
mLastY = y;
mLastX = x;
if (mEventListener != null) {
mEventListener.onDown(x, y);
}
}
break;
case MotionEvent.ACTION_MOVE: {
if (Math.abs(x - mStartX) < distance
&& Math.abs(y - mStartY) < distance) {
if (mState == TouchState.STATE_STOP) {
break;
}
} else if (mState != TouchState.STATE_MOVE) {
mState = TouchState.STATE_MOVE;
}
if (mEventListener != null) {
mEventListener.onMove(mLastX, mLastY, x - mLastX, y - mLastY);
}
mLastY = y;
mLastX = x;
mState = TouchState.STATE_MOVE;
}
break;
case MotionEvent.ACTION_UP: {
if (mEventListener != null) {
mEventListener.onUp(x, y);
}
if (mState != TouchState.STATE_MOVE
&& event.getEventTime() - event.getDownTime() < MIN_TAP_TIME) {
v.performClick();
}
mState = TouchState.STATE_STOP;
}
break;
default:
break;
}
return true;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mService == null)
return false;
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
(forward ? mNext : mPrevious).setImageResource(this.pressed);
possibleSeek = (int) mService.getTime();
mPreviewingSeek = true;
vibrated = false;
length = mService.getLength();
h.postDelayed(seekRunnable, 1000);
return true;
case MotionEvent.ACTION_UP:
(forward ? mNext : mPrevious).setImageResource(this.normal);
h.removeCallbacks(seekRunnable);
mPreviewingSeek = false;
if(event.getEventTime()-event.getDownTime() < 1000) {
if(forward)
onNextClick(v);
else
onPreviousClick(v);
} else {
if(forward) {
if(possibleSeek < mService.getLength())
mService.setTime(possibleSeek);
else
onNextClick(v);
} else {
if(possibleSeek > 0)
mService.setTime(possibleSeek);
else
onPreviousClick(v);
}
}
return true;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
float x = event.getX();
float y = event.getY();
float deltaX = Math.abs(x - mFirstDownX);
float deltaY = Math.abs(y - mFirstDownY);
switch (action) {
case MotionEvent.ACTION_DOWN:
attemptClaimDrag();
mFirstDownX = x;
mFirstDownY = y;
mCurBtnPic = mBtnPressed;
mBtnInitPos = mChecked ? mBtnOnPos : mBtnOffPos;
break;
case MotionEvent.ACTION_MOVE:
float time = event.getEventTime() - event.getDownTime();
mBtnPos = mBtnInitPos + event.getX() - mFirstDownX;
if (mBtnPos >= mBtnOffPos) {
mBtnPos = mBtnOffPos;
}
if (mBtnPos <= mBtnOnPos) {
mBtnPos = mBtnOnPos;
}
mTurningOn = mBtnPos > (mBtnOffPos - mBtnOnPos) / 2 + mBtnOnPos;
mRealPos = getRealPos(mBtnPos);
break;
case MotionEvent.ACTION_UP:
mCurBtnPic = mBtnNormal;
time = event.getEventTime() - event.getDownTime();
if (deltaY < mTouchSlop && deltaX < mTouchSlop && time < mClickTimeout) {
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
} else {
startAnimation(!mTurningOn);
}
break;
}
invalidate();
return isEnabled();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
float x = event.getX();
float y = event.getY();
float deltaX = Math.abs(x - mFirstDownX);
float deltaY = Math.abs(y - mFirstDownY);
switch (action) {
case MotionEvent.ACTION_DOWN:
ViewParent mParent = getParent();
if (mParent != null) {
// 通知父控件不要拦截本view的触摸事件
mParent.requestDisallowInterceptTouchEvent(true);
}
mFirstDownX = x;
mFirstDownY = y;
bmCurBtnPic = bmBtnPressed;
startBtnPos = mChecked ? onBtnPos : offBtnPos;
break;
case MotionEvent.ACTION_MOVE:
float time = event.getEventTime() - event.getDownTime();
curBtnPos = startBtnPos + event.getX() - mFirstDownX;
if (curBtnPos >= onBtnPos) {
curBtnPos = onBtnPos;
}
if (curBtnPos <= offBtnPos) {
curBtnPos = offBtnPos;
}
mTurningOn = curBtnPos > bgWidth / 2 - btnWidth / 2;
break;
case MotionEvent.ACTION_UP:
bmCurBtnPic = bmBtnNormal;
time = event.getEventTime() - event.getDownTime();
if (deltaY < mTouchSlop && deltaX < mTouchSlop && time < mClickTimeout) {
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClick();
}
} else {
startAnimation(mTurningOn);
}
break;
}
invalidate();
return isEnabled();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled() || !isClickable()) {
return false;
}
int action = event.getAction();
float deltaX = event.getX() - mStartX;
float deltaY = event.getY() - mStartY;
// status the view going to change to when finger released
boolean nextStatus;
switch (action) {
case MotionEvent.ACTION_DOWN:
catchView();
mStartX = event.getX();
mStartY = event.getY();
mLastX = mStartX;
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
setProcess(getProcess() + (x - mLastX) / mSafeRectF.width());
mLastX = x;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
setPressed(false);
nextStatus = getStatusBasedOnPos();
float time = event.getEventTime() - event.getDownTime();
if (deltaX < mTouchSlop && deltaY < mTouchSlop && time < mClickTimeout) {
performClick();
} else {
if (nextStatus != isChecked()) {
playSoundEffect(SoundEffectConstants.CLICK);
setChecked(nextStatus);
} else {
animateToState(nextStatus);
}
}
break;
default:
break;
}
return true;
}
/**
* Gets all the touch events and updates dragging related logic. Note that if this app menu
* is initiated by software UI control, then the control should set onTouchListener and forward
* all the events to this method because the initial UI control that processed ACTION_DOWN will
* continue to get all the subsequent events.
*
* @param event Touch event to be processed.
* @param button Button that received the touch event.
* @return Whether the event is handled.
*/
boolean handleDragging(MotionEvent event, View button) {
if (!mAppMenu.isShowing() || !mDragScrolling.isRunning()) return false;
// We will only use the screen space coordinate (rawX, rawY) to reduce confusion.
// This code works across many different controls, so using local coordinates will be
// a disaster.
final float rawX = event.getRawX();
final float rawY = event.getRawY();
final int roundedRawX = Math.round(rawX);
final int roundedRawY = Math.round(rawY);
final int eventActionMasked = event.getActionMasked();
final long timeSinceDown = event.getEventTime() - event.getDownTime();
final ListView listView = mAppMenu.getPopup().getListView();
mLastTouchX = rawX;
mLastTouchY = rawY;
mMenuButtonScreenCenterY = getScreenVisibleRect(button).centerY();
if (eventActionMasked == MotionEvent.ACTION_CANCEL) {
mAppMenu.dismiss();
return true;
} else if (eventActionMasked == MotionEvent.ACTION_UP) {
nativeRecordAppMenuTouchDuration(timeSinceDown);
}
mIsSingleTapCanceled |= timeSinceDown > mTapTimeout;
mIsSingleTapCanceled |= !pointInView(button, event.getX(), event.getY(), mScaledTouchSlop);
if (!mIsSingleTapCanceled && eventActionMasked == MotionEvent.ACTION_UP) {
RecordUserAction.record("MobileUsingMenuBySwButtonTap");
finishDragging();
}
// After this line, drag scrolling is happening.
if (!mDragScrolling.isRunning()) return false;
boolean didPerformClick = false;
int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL;
switch (eventActionMasked) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
itemAction = ITEM_ACTION_HIGHLIGHT;
break;
case MotionEvent.ACTION_UP:
itemAction = ITEM_ACTION_PERFORM;
break;
default:
break;
}
didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction);
if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) {
RecordUserAction.record("MobileUsingMenuBySwButtonDragging");
mAppMenu.dismiss();
} else if (eventActionMasked == MotionEvent.ACTION_MOVE) {
// Auto scrolling on the top or the bottom of the listView.
if (listView.getHeight() > 0) {
float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO,
mItemRowHeight * 1.2f / listView.getHeight());
float normalizedY =
(rawY - getScreenVisibleRect(listView).top) / listView.getHeight();
if (normalizedY < autoScrollAreaRatio) {
// Top
mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f)
* mAutoScrollFullVelocity;
} else if (normalizedY > 1.0f - autoScrollAreaRatio) {
// Bottom
mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f)
* mAutoScrollFullVelocity;
} else {
// Middle or not scrollable.
mDragScrollingVelocity = 0.0f;
}
}
}
return true;
}
/**
* Test if a MotionEvent with the given start and end offsets
* can be considered as a "click".
* @param upEvent The final finger-up event.
* @param xDown The x-offset of the down event.
* @param yDown The y-offset of the down event.
* @param xUp The x-offset of the up event.
* @param yUp The y-offset of the up event.
* @return true if it's a click, false otherwise
*/
private boolean isClick(MotionEvent upEvent, float xDown, float yDown, float xUp, float yUp) {
if (upEvent == null) return false;
long time = upEvent.getEventTime() - upEvent.getDownTime();
float distance = PointF.length( //
xDown - xUp, //
yDown - yUp);
return time < MAX_CLICK_TIME && distance < MAX_CLICK_DISTANCE;
}