1.使用 onTouchEvent事件監聽器或者使用 setOnTouchEventListener監聽觸摸事件javascript
2.事件類型的判斷java
event.getAction()或者event.getActionMask(),注意,前者包含後者,後者判斷起來比較精確android
3.事件的生命週期 Action_DOWN(按下) ---> Action_MOVE(移動) --->Action_UP/Action_CANCELED(擡起手指或者滑出屏幕)ide
在一些事件,如Click,LongClick等事件按照該週期的時間長度和 移動位置來決定的測試
4.事件傳遞的3個階段ui
第一階段是 分發/攔截階段 ondispatchEvent和onInteceptorEvent(通常在此階段處理事件,可能致使事件沒法傳遞)this
第二階段是 向下傳遞階段 onTouchEventspa
學過javascript的讀者可能會發現,這種事件的傳遞和js的十分相似,不過少了一個階段就是 目標View處理階段,按照javascript的劃分,code
第一個階段 捕獲階段(不管如何處理,事件總會傳遞到目標控件)orm
第二個階段 目標控件事件處理階段
第三個階段 冒泡階段(這個階段處理事件的比較多,可終止冒泡)
很顯然,android的事件傳遞階段彷佛很不友好,由於此階段捕獲致使不少處理衝突,甚至目標控件沒法獲得事件,好比ViewGroup攔截事件以後,將直接把事件交給本身的onTouchEvent進行處理,形成子View上的事件處理程序一直沒法執行,不少時候因爲這種事件分發問題致使的錯誤很是多,所以對於這種問題的處理要務必格外當心,若是遇到這種衝突,通常的作法是 2個聯繫密切的 View控件分別綁定事件,並調用getParent().requestDisallowInterceptTouchEvent(true),但這種方法也是由侷限性的,但願有更好想法的讀者指正一下。
5.多點觸摸事件的處理,對於多點觸摸,可使用
event.getPointersCount()或者觸摸點的數量,而後經過 event.getX(index) ,event.getY(index)得到觸摸點的座標
public class MultiTouchActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_multi_touch); } public boolean onTouchEvent(MotionEvent event) { // ֻ2個手指 if(event.getPointerCount() == 2) { if(event.getAction() == MotionEvent.ACTION_MOVE) { int historySize = event.getHistorySize(); if(historySize == 0) return true; //第1個手指的Y座標 float currentY1 = event.getY(0); //第1個手指的歷史縱座標 float historyY1 = event.getHistoricalY(0, historySize - 1); //第二個手指的的Y座標 float currentY2 = event.getY(1); //第2個手指的歷史縱座標 float historyY2 = event.getHistoricalY(1,historySize - 1); float distance = Math.abs(currentY1 - currentY2); float historyDistance = Math.abs(historyY1 - historyY2); if(distance > historyDistance) { Log.d("status", "放大"); } else if(distance < historyDistance) { Log.d("status", "縮小"); } else { Log.d("status", "平行移動"); } } } return true; } }
public class DrawGestureTest extends Activity implements OnGesturePerformedListener { private GestureOverlayView mDrawGestureView; private static GestureLibrary sStore; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDrawGestureView = (GestureOverlayView)findViewById(R.id.gesture); //設置手勢可多筆畫繪製,默認狀況爲單筆畫繪製 mDrawGestureView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE); //設置手勢的顏色(藍色) mDrawGestureView.setGestureColor(gestureColor(R.color.gestureColor)); //設置還沒未能造成手勢繪製是的顏色(紅色) mDrawGestureView.setUncertainGestureColor(gestureColor(R.color.ungestureColor)); //設置手勢的粗細 mDrawGestureView.setGestureStrokeWidth(4); /*手勢繪製完成後淡出屏幕的時間間隔,即繪製完手指離開屏幕後相隔多長時間手勢從屏幕上消失; * 能夠理解爲手勢繪製完成手指離開屏幕後到調用onGesturePerformed的時間間隔 * 默認值爲420毫秒,這裏設置爲0.5秒 */ mDrawGestureView.setFadeOffset(500); //綁定監聽器 mDrawGestureView.addOnGesturePerformedListener(this); //建立保存手勢的手勢庫 createStore(); } private void createStore() { File mStoreFile = null; /*判斷mStoreFile是爲空。 * 判斷手機是否插入SD卡,而且應用程序是否具備訪問SD卡的權限 */ if (mStoreFile == null && Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { mStoreFile = new File(Environment.getExternalStorageDirectory(), "mygesture"); } if (sStore == null) { /* 另外三種建立保存手勢文件的方式以下: //保存手勢的文件在手機SD卡中 sStore = GestureLibraries.fromFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "mygesture"); sStore = GestureLibraries.fromPrivateFile(this, Environment.getExternalStorageDirectory().getAbsolutePath + "mygesture"); //保存手勢的文件在應用程序的res/raw文件下 sStore = GestureLibraries.fromRawResource(this, R.raw.gestures); */ sStore = GestureLibraries.fromFile(mStoreFile); } testLoad(); } //測試保存手勢的文件是否建立成功 private void testLoad() { if (sStore.load()) { showMessage("手勢文件裝載成功"); } else { showMessage("手勢文件裝載失敗"); } } public static GestureLibrary getStore() { return sStore; } //手勢繪製完成時調用 @Override public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { // TODO Auto-generated method stub creatDialog(gesture); } private void creatDialog(final Gesture gesture) { View dialogView = getLayoutInflater().inflate(R.layout.show_gesture, null); //imageView用於顯示繪製的手勢 ImageView imageView = (ImageView) dialogView.findViewById(R.id.show); //獲取用戶保存手勢的名字 EditText editText = (EditText)dialogView.findViewById(R.id.name); final String name = editText.getText().toString(); // 調用Gesture的toBitmap方法造成對應手勢的位圖 final Bitmap bitmap = gesture.toBitmap(128, 128, 10, gestureColor(R.color.showColor)); imageView.setImageBitmap(bitmap); Builder dialogBuider = new AlertDialog.Builder(DrawGestureTest.this); dialogBuider.setView(dialogView); //綁定對話框的確認按鈕監聽事件 dialogBuider.setPositiveButton( "保存", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 添加手勢 sStore.addGesture(name, gesture); // 保存添加的手勢 sStore.save(); } }); //綁定對話框的取消按鈕監聽事件 dialogBuider.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); //顯示對話框 dialogBuider.show(); } private int gestureColor(int resId) { return getResources().getColor(resId); } private void showMessage(String s) { Toast.makeText(this, s, Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); //移除綁定的監聽器 mDrawGestureView.removeOnGesturePerformedListener(this); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.gesture.GestureOverlayView android:id="@+id/gesture" android:layout_width="fill_parent" android:layout_height="fill_parent" > </android.gesture.GestureOverlayView> </LinearLayout>
對話框show_gesture.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:text="@string/set_gesture_name"/> <EditText android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <ImageView android:id="@+id/show" android:layout_gravity="center" android:layout_width="128dp" android:layout_height="128dp" android:layout_marginTop="10dp"/> </LinearLayout>