1. 程式人生 > >Android單點觸控與多點觸控

Android單點觸控與多點觸控

測試單點觸控事件,它適用於所有android版本。我們在檢視中註冊一個OnTouchListener介面,並把觸控時間傳遞給這個介面實現。OnTouchListener介面只有一個方法:public abstract boolean onTouch(View  v, MotionEvent event)

第一個引數是分派該觸控事件的View,第二個引數是獲得觸控事件的引數。

OnTouchListener可在任何View中實現中通過View.setOnTouchListener方法進行註冊。在MotionEvent被分派給View本身之前會先呼叫OnTouchListener方法。我們可在onTouch()方法的實現中返回true通知該View,我們已經處理事件。如果返回為false,那麼View將自己處理該事件。

MotionEvent例項包含如下3個我們關心的方法:

MotionEvent.getX()和MotionEvent.getY();這兩個方法報告觸控事件相對於View的X和Y座標。座標原點位於該檢視左上角,X軸指向右邊,Y軸指向下。座標是以畫素為單位。該方法返回浮點型資料,因此該座標具有亞畫素精度。

MotionEvent.getAction():返回觸控事件的型別。它是一個整型數,具有如下值之一:MotionEvent.ACTION_DOWN、

MotionEvent.ACTION_MOVE、MotionEvent.ACTION_CANCEL和MotionEvent.ACTION_UP。

顧名思義,當手指觸控式螢幕幕時,將觸發MotionEvent.ACTION_DOWN事件。

當手指移動時,則觸發MotionEvent.ACTION_MOVE事件。只要手指沒有完全脫離螢幕,總可以獲得MotionEvent.ACTION_MOVE事件

當手指再次離開螢幕時,MotionEvent.ACTION_UP事件就會觸發。

MotionEvent.ACTION_CANCEL事件則稍微神祕。文件說明當前手勢取消時會觸發該事件,我們還是把它假設為MotionEvent.ACTION_UP事件。

下面是測試程式碼:

  1. package org.example.ch04_android_basics;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.util.Log;  
  5. import android.view.MotionEvent;  
  6. import android.view.View;  
  7. import android.view.View.OnTouchListener;  
  8. import android.widget.TextView;  
  9. publicclass SingleTouchTest extends Activity implements OnTouchListener{  
  10.     StringBuilder builder = new StringBuilder();  
  11.     TextView textView;  
  12.     @Override
  13.     publicboolean onTouch(View v, MotionEvent event) {  
  14.         // TODO Auto-generated method stub
  15.         builder.setLength(0);  
  16.         switch(event.getAction()){  
  17.         case MotionEvent.ACTION_DOWN:  
  18.             builder.append("down, ");  
  19.             break;  
  20.         case MotionEvent.ACTION_MOVE:  
  21.             builder.append("move, ");  
  22.             break;  
  23.         case MotionEvent.ACTION_CANCEL:  
  24.             builder.append("cancle, ");  
  25.             break;  
  26.         case MotionEvent.ACTION_UP:  
  27.             builder.append("up, ");  
  28.             break;  
  29.         }  
  30.         builder.append(event.getX());  
  31.         builder.append(", ");  
  32.         builder.append(event.getY());  
  33.         String text = builder.toString();  
  34.         Log.d("TouchTest", text);  
  35.         textView.setText(text);  
  36.         returntrue;  
  37.     }  
  38.     @Override
  39.     protectedvoid onCreate(Bundle savedInstanceState) {  
  40.         // TODO Auto-generated method stub
  41.         super.onCreate(savedInstanceState);  
  42.         textView = new TextView(this);  
  43.         textView.setText("Touch and drag (one finger only)!");  
  44.         textView.setOnTouchListener(this);  
  45.         setContentView(textView);  
  46.     }  
  47. }  

    對於處理多點觸控事件就複雜的多,Android2.2版本後對多點觸控做了修改,添加了新的方法和常量,甚至重新命名了常量。這些改變可能會讓處理多點觸控容易些。不過只支援Android2.2以後的版本,為了支援Android2.0--Android2.21版本,我們使用Android2.0的API。

    當處理多點觸控事件時,我們使用過載的方法,它們帶有一個所謂的指標索引,如event.getX(pointerIndex);

    pointIndex是MotionEvent的內部陣列中的一個索引,它包含特定手指觸控式螢幕幕事件的座標值。而真正識別螢幕上的一根手指是指標ID。指標ID是一個任意數字,可以唯一標識觸控式螢幕幕的一個指標的例項。有一個方法MotionEvent.getPointerIdentifier(int pointerIndex),它返回一個基於指標索引的指標ID。只要手指還觸控在螢幕上,一個指標ID就與一根手指保持相同,而指標索引就不一定這樣了。先來看看是如何獲取指標索引:

    int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;

    ACTION_POINTER_ID_MASK的常量的值是0xff00,因此低8位為0,高8位為15,用於儲存事件的指標索引。

    整數的低8位可從event.getAction()方法返回得到,用於儲存事件型別的值。我們通過MotionEvent.ACTION_POINTER_ID_SHIFT來移位,該值為8,因此實際上是將第15位移到第8位,第7位移到第0位。注意我們是獲取pointerIndex而常量卻是XXX_POINTER_ID_XXX而不是XXX_POINTER_INDEX_XXX

    獲取事件型別,我們只需遮蔽指標索引:

    int action = event.getAction() & MotionEvent.ACTION_MASK;

    這裡我們會遇到新的事件型別,

    MotionEvent.ACTION_POINTER_DOWN:除了第一根手指外的任何手指觸控式螢幕幕,都將發生該事件,而第一根手指仍然產生MotionEvent.ACTION_DOWN事件。

    MotionEvent.ACTION_POINTER_UP:多根手指觸控式螢幕幕而一根手指離開螢幕時,將發生該事件。最後一根手指離開螢幕將產生MotionEvent.ACTION_UP事件,而該手指不一定是第一個觸控式螢幕幕的手指。為了檢查單個MotionEvent中包含幾個事件,可使用MotionEvent.getPointerCount()方法,它會告訴我們MotionEvent中包含多少根手指的座標。然後我們可通過MotionEvent.getX()、

    MotionEvent.getY()和MotionEvent.getPointerId()方法來得到指標ID和從指標索引0到MotionEvent.getPointerCount() - 1的座標值。

    測試程式碼如下:

    1. package org.example.ch04_android_basics;  
    2. import android.app.Activity;  
    3. import android.os.Bundle;  
    4. import android.view.MotionEvent;  
    5. import android.view.View;  
    6. import android.view.View.OnTouchListener;  
    7. import android.widget.TextView;  
    8. publicclass MultiTouchTest extends Activity implements OnTouchListener {  
    9.     StringBuilder builder = new StringBuilder();  
    10.     TextView textView;  
    11.     float[] x = newfloat[10];  
    12.     float[] y = newfloat[10];  
    13.     boolean[] touched = newboolean[10];  
    14.     int[] id = newint[10];  
    15.     privatevoid updateTextView(){  
    16.         builder.setLength(0);  
    17.         for(int i = 0; i < 10; i++){  
    18.             builder.append(touched[i]);  
    19.             builder.append(", ");  
    20.             builder.append(id[i]);  
    21.             builder.append(", ");  
    22.             builder.append(x[i]);  
    23.             builder.append(", ");  
    24.             builder.append(y[i]);  
    25.             builder.append("\n");  
    26.         }  
    27.         textView.setText(builder);  
    28.     }  
    29.     @Override
    30.     protectedvoid onCreate(Bundle savedInstanceState) {  
    31.         // TODO Auto-generated method stub
    32.         super.onCreate(savedInstanceState);  
    33.         textView = new TextView(this);  
    34.         textView.setText("Touch and drag (multiple fingers supported)!");  
    35.         textView.setOnTouchListener(this);  
    36.         setContentView(textView);  
    37.         for(int i = 0; i < 10; i++){  
    38.             id[i] = -1;  
    39.         }  
    40.         updateTextView();  
    41.     }  
    42.     @Override
    43.     publicboolean onTouch(View v, MotionEvent event) {  
    44.         // TODO Auto-generated method stub
    45.         int action = event.getAction() & MotionEvent.ACTION_MASK;  
    46.         int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >>  
    47.             MotionEvent.ACTION_POINTER_ID_SHIFT;  
    48.         int pointerCount = event.getPointerCount();  
    49.         for(int i = 0; i < 10; i++){  
    50.             if(i >= pointerCount){  
    51.                 touched[i] = false;  
    52.                 id[i] = -1;  
    53.                 continue;  
    54.             }  
    55.             if(event.getAction() != MotionEvent.ACTION_MOVE && i != pointerIndex){  
    56.                 /* If it's an up/down/cancel/out event, mask the id to see if  
    57.                 we should process it for this touch point */
    58.                 continue;  
    59.             }  
    60.             int pointerId = event.getPointerId(i);  
    61.             switch(action){  
    62.             case MotionEvent.ACTION_DOWN:  
    63.             case MotionEvent.ACTION_POINTER_DOWN:  
    64.                 touched[i] = true;  
    65.                 id[i] = pointerId;  
    66.                 x[i] = (int)event.getX(i);  
    67.                 y[i] = (int)event.getY(i);  
    68.                 break;  
    69.             case MotionEvent.ACTION_UP:  
    70.             case MotionEvent.ACTION_POINTER_UP:  
    71.             case MotionEvent.ACTION_OUTSIDE:  
    72.             case MotionEvent.ACTION_CANCEL:  
    73.                 touched[i] = false;  
    74.                 id[i] = -1;  
    75.                 x[i] = (int)event.getX(i);  
    76.                 y[i] = (int)event.getY(i);  
    77.                 break;  
    78.             case MotionEvent.ACTION_MOVE:  
    79.                 touched[i] = true

      相關推薦

      Android觸控觸控

      先測試單點觸控事件,它適用於所有android版本。我們在檢視中註冊一個OnTouchListener介面,並把觸控時間傳遞給這個介面實現。OnTouchListener介面只有一個方法:public abstract boolean onTouch(View  v,

      Android-防止使用者快速選和觸控

      1.為什麼要防止使用者重複點選在使用者使用App的時候,並不會乖乖的按照我們的想法而執行。下面就拿我們熟悉的Button來:舉個栗子假設這個Button的點選事件是“一個登入的網路請求”,這時候我們的主角-老司機小明登場了,他嫻熟的輸入了自己的賬號和密碼,然後點選了登入,靜靜地等候著APP的反饋跳轉,可是天有

      Unity判斷手勢的滑動方向,觸控觸控,並獲取剛觸控以及觸控結束事的座標

      Unity判斷手勢觸控的型別 ,判斷手勢的滑動方向,並獲取剛觸控以及觸控結束事的座標 本章咱們一起來看下unity對有觸控手勢做出的響應 單點觸控 Input.touchCount==1 移動觸控 Input.GetTouch(0).phase==TouchPhas

      Android自定義View的觸控

      在Android遊戲開發中,自定義View的多點觸控技術必不可少,本文主要簡單講解下Android中多點觸控技術的基礎知識。 所謂多點觸控技術,就是手機螢幕上支援同時處理多個觸控點的觸屏或移動事件。多點觸控的關鍵點有以下三點:(1)需要LCD和應用程式同時支援;

      iOS新增擊手勢tableview選的衝突問題

      #pragma mark-手勢代理,解決和tableview點擊發生的衝突 新增代理方法 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestur

      驗證,語言支持,CI

      加載 load for 控制器 cati 驗證 pan conf span 表單驗證將漢化包,復制到application文件夾下的language,然後在config.php中,將語音改為simplified-chinese,和漢化包文件夾的名字一致。 對於隨漢化包帶來

      部署KVM虛擬化(網橋網橋VLAN模式)

      狀態 開機啟動 modprobe 刪除 shutdown ren 3.2 子目錄 eve 本案例單網橋模式實驗在虛擬機中部署1、開啟虛擬機虛擬化功能2、關閉selinux和firewalld 3、通過命令查看server是否支持虛擬化 -- egrep ‘(vmx|svm

      《JAVA線程編程核心技術》 筆記:第六章:例模式線程

      會有 isp left sync con 多線程編程 鎖機制 數據 range 一、立即加載/"餓漢模式"和延遲加載/"懶漢模式" 立即加載(又稱餓漢模式):在使用類的時候已經將對象創建完畢,常見實現方法是直接new實例化 延遲加載(又稱懶漢模式):在調用get

      Java線程核心技術(五)例模式線程

      otf 實現 https 但是 not hashcode int 線程編程 代碼包 本文只需要考慮一件事:如何使單例模式遇到多線程是安全的、正確的 1.立即加載 / "餓漢模式" 什麽是立即加載?立即加載就是使用類的時候已經將對象創建完畢,常見的實現

      js、jq和標籤裡面設定按鈕可不可選狀態

      <button id="bt1" type="button">button</button> 1、js中設定按鈕可點選與不可點選,預設是可點選的 (1)設定按鈕不可點選 document.getElementById("bt1").disabled=ture;

      第六章例模式執行緒——立即載入“餓漢模式”延遲載入“懶漢模式”

      立即載入就是使用類的時候已經將物件建立完畢了,也稱為“餓漢模式” package test01; public class MyObject { // 建立物件 private static MyObject object = new MyObject(); private MyObjec

      Java執行緒學習筆記21之例模式執行緒

      詳細程式碼見:github程式碼地址   第六章 單例模式與多執行緒 前言: 我之前已經開設了23個設計模式這個專欄,介紹了很多的Java設計模式,其中一些模式對於絕 大多數程式語言設計思想都是類似的,需要了解單例模式的可以去看看。 我們在實際開發中經常用到單例模式,但

      例模式執行緒之間的關係總結

      給大家推薦個靠譜的公眾號程式設計師探索之路,大家一起加油 單例模式與多執行緒之間的關係總結(魔怔多執行緒中~~~~~)   近日筆者被多執行緒與單例物件之間的關係產生了混淆。通過了一段時間的查閱,理清了兩者之間的管理,現做筆記梳理。如有不足,歡迎指出:) 在我在考慮考慮他們的時候思考了以

      Java執行緒核心技術(五)例模式執行緒

      本文只需要考慮一件事:如何使單例模式遇到多執行緒是安全的、正確的 1.立即載入 / "餓漢模式" 什麼是立即載入?立即載入就是使用類的時候已經將物件建立完畢,常見的實現辦法就是直接 new 例項化。 public class MyObject { private static MyObject m

      MySQL---當Java遇上MySQL⑤---執行緒執行緒下的事務

      事務transaction 原子性(atomicity):組成事務處理的語句形成了一個邏輯單元,不能只執行其中的一部分。 一致性(consistency):在事務處理執行前後,資料庫是一致的(資料庫資料完整性約束)。 隔離性(isolcation):一個事務處理對另

      CSS 實現自定義樣式的選框選框

      前端在開發的過程中,經常會遇見使用單選框以及多選框的情況,但是預設的選框按鈕的樣式單一,一般我們需要去自定義一些選框按鈕的樣式; 通常情況下,單選、多選為方便自定義樣式,一般會採用input+

      【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗三:按鍵模組② —

      實驗三:按鍵模組② — 點選與長點選 實驗二我們學過按鍵功能模組的基礎內容,其中我們知道按鍵功能模組有如下操作: l 電平變化檢測; l 過濾抖動; l 產生有效按鍵。 實驗三我們也會z執行同樣的事情,不過卻是產生不一樣的有效按鍵: l 按下有效(點選); l 長按下有效(長點選)。 圖3

      Android Studio:服務執行緒--簡單音樂播放器

      一、 實驗題目   服務與多執行緒--簡單音樂播放器 【目的】 1. 學會使用 MediaPlayer; 2. 學會簡單的多執行緒程式設計,使用 Handle 更新 UI; 3. 學會使用 Service 進行後臺工作; 4. 學會使用 Service 與 Activit

      .NET Framework中定時器timer的執行緒執行緒使用講解

      如果你需要使用規律的時間間隔重複執行一些方法,最簡單的方式是使用定時器(timer)。與下邊的例子相比,定時器可以便捷、高效地使用記憶體和資源: ? 1 2 3 4 5 6 7 new Thread (delegate() { while (enabled)

      【Java執行緒】例模式執行緒

      單例模式大家都不陌生,即讓一個類只有一個例項。 單例模式分為懶漢式和餓漢式。 懶漢式☞方法呼叫時再例項化物件,什麼時候用什麼時候例項化,比較懶。 餓漢式☞方法呼叫前物件就已經建立好了,比較有捉急。 本文著重描述懶漢式與多執行緒的內容。 1.餓漢式 public