編輯:關於Android編程
之前的文章層從Framework層介紹了Android Touch事件即(MotionEvent)的傳遞機制。本文將詳細介紹MotionEvent的一些成員和方法。了解了MotionEvent對開發一些特效如拖動控件或多點縮放控件有很大的作用。同時,掌握MotionEvent類也是學好android觸控技術的基礎。
一、一些常量
常見的動作常量:
public static final int ACTION_DOWN = 0;單點觸摸動作
public static final int ACTION_UP = 1;單點觸摸離開動作
public static final int ACTION_MOVE = 2;觸摸點移動動作
public static final int ACTION_CANCEL = 3;觸摸動作取消
public static final int ACTION_OUTSIDE = 4;觸摸動作超出邊界
public static final int ACTION_POINTER_DOWN = 5;多點觸摸動作
public static final int ACTION_POINTER_UP = 6;多點離開動作
以下是一些非touch事件
public static final int ACTION_HOVER_MOVE = 7;
public static final int ACTION_SCROLL = 8;
public static final int ACTION_HOVER_ENTER = 9;
public static final int ACTION_HOVER_EXIT = 10;
掩碼常量
ACTION_MASK = 0X000000ff
動作掩碼
ACTION_POINTER_INDEX_MASK = 0X0000ff00
觸摸點索引掩碼
ACTION_POINTER_INDEX_SHIFT = 8 獲取觸摸點索引需要移動的位數
二、相關方法
getAction()方法返回的是int類型,用到的只有低16位,其中:低八位是動作的類型,高8位是觸摸點索引值的表示(單點為0,雙點為1)
獲得動作類型: int action = event.getAction() & ACTION_MASK 或者使用 getActionMasked()
獲得觸摸點索引類型: int pointerIndex = (event.getAction() & ACTION_POINTER_INDEX_MASK ) >> ACTION_POINTER_INDEX_SHIFT
或者使用 getActionIndex()
為什麼要有索引信息?
有了索引信息,我們可以在onTOuchEvent事件中判斷傳進來的MotionEvent對象對應的是單點信息還是多點信息。
下面的代碼段能使用戶在屏幕上拖動一個對象。它記錄了初始點的位置,計算點移動的距離,並將對象移動到新的位置。它正確的處理了這種情況:當第一個手指把控件拖到一個位置,然後按下第二個手指,且第二個手指與同一個控件上。當用戶抬起第一個手指時,控件不會跑到第二個手指的位置同時第二個手指可以繼續拖動控件。
// The ‘active pointer’ is the one currently moving our object. private int mActivePointerId = INVALID_POINTER_ID; @Override public boolean onTouchEvent(MotionEvent ev) { // Let the ScaleGestureDetector inspect all events. mScaleDetector.onTouchEvent(ev); final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_DOWN: { final int pointerIndex = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); // Remember where we started (for dragging) mLastTouchX = x; mLastTouchY = y; // Save the ID of this pointer (for dragging) mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; } case MotionEvent.ACTION_MOVE: { // Find the index of the active pointer and fetch its position final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); // Only move if the ScaleGestureDetector isn't processing a gesture. if (!mScaleDetector.isInProgress()) { // Calculate the distance moved final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; invalidate(); } // Remember this touch position for the next move event mLastTouchX = x; mLastTouchY = y; break; } case MotionEvent.ACTION_UP: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = MotionEventCompat.getActionIndex(ev); final int pointerId = MotionEventCompat.getPointerId(ev, 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; mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex); mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex); mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); } break; } } return true; }
MotionEvent還包含了移動操作中其它歷史移動數據以方便處理觸控的移動操作.
android sdk對於這個類的描述中就有這麼一句:
For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object.
簡介這個輪子是對RecyclerView的封裝,主要完成了下拉刷新、上拉加載更多、RecyclerView頭部。在我的Material Design學習項目中使用到了項目
解釋一下,上面的sinX和cosX,表示旋轉角度的cos值和sin值,注意,旋轉角度是按順時針方向計算的。 translateX
package com.example.baidulocdemo_2;import com.baidu.location.BDLocationListener;impor
本文為大家分享了Android游戲開發之碰撞檢測,供大家參考,具體內容如下矩形碰撞 原理: 兩個矩形位置 的四種情況 不是這四中情況 則碰撞圓形碰撞 原理: 利用兩個圓心