Android事件處理 – Android移動開發技術文章_手機開發 Android移動開發教學課程

目的:通過全面的分析Android的鼠標和鍵盤事件。瞭解Android中如何接收和處理鍵盤和鼠標事件,以及如何用代碼來產生事件。
主要學習內容:
1. 接收並處理鼠標事件:按下、彈起、移動、雙擊、長按、滑動、滾動
2. 接收並處理按鍵事件:按下、彈起
3. 模擬鼠標/按鍵事件

1. Android事件
現代的用戶界面,都是以事件來驅動的來實現人機交換的,而Android上的一套UI控件,無非就是派發鼠標和鍵盤事件,然後每個控件收到相應的事件之後,做相應的處理。如Button控件,就隻需要處理Down、move、up這幾個事件,Down的時候重繪控件,move的時候一般也需要重繪控件,當up的時候,重繪控件,然後產生onClick事件。在Android中通過實現OnClickListener接口的onClick方法來實現對Button控件的處理。
對於觸摸屏事件(鼠標事件)有按下有:按下、彈起、移動、雙擊、長按、滑動、滾動。按下、彈起、移動(down、move、up)是簡單的觸摸屏事件,而雙擊、長按、滑動、滾動需要根據運動的軌跡來做識別的。在Android中有專門的類去識別,android.view.GestureDetector。
對於按鍵(keyevent),無非就是按下、彈起、長按等。
2. Android事件處理
Android手機的坐標系是以左上定點為原點坐標(0,0), 向右為X抽正方形,向下為Y抽正方向。
2.1 簡單觸摸屏事件
在Android中任何一個控件和Activity都是間接或者直接繼承於android.view.View。一個View對象可以處理測距、佈局、繪制、焦點變換、滾動條,以及觸屏區域自己表現的按鍵和手勢。當我們重寫View中的onTouchEvent(MotionEvent)方法後,就可以處理簡單的觸摸屏事件。
代碼如下:
view plaincopy to clipboardprint?
public boolean onTouchEvent(MotionEvent event)  
    {  
        int events[] = {MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE,  
                MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE,  
                MotionEvent.ACTION_POINTER_DOWN,MotionEvent.ACTION_POINTER_UP,  
                MotionEvent.EDGE_TOP,MotionEvent.EDGE_BOTTOM,MotionEvent.EDGE_LEFT,MotionEvent.EDGE_RIGHT}; 
          
        String szEvents[]={"ACTION_DOWN", "ACTION_MOVE",  
        "ACTION_UP", "ACTION_MOVE", "ACTION_CANCEL", "ACTION_OUTSIDE",  
        "ACTION_POINTER_DOWN","ACTION_POINTER_UP",  
        "EDGE_TOP","EDGE_BOTTOM","EDGE_LEFT","EDGE_RIGHT"};  
        for(int i=0; i < events.length; i++)  
        {  
            if(events[i] == event.getAction())  
            {  
                if(oldevent != event.getAction())  
                {  
                    DisplayEventType(szEvents[i]);  
                    oldevent = event.getAction();  
                }  
                break;  
            }  
        }  
        return super.onTouchEvent(event);  
    } 
public boolean onTouchEvent(MotionEvent event)
 {
  int events[] = {MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE,
    MotionEvent.ACTION_UP, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE,
    MotionEvent.ACTION_POINTER_DOWN,MotionEvent.ACTION_POINTER_UP,
    MotionEvent.EDGE_TOP,MotionEvent.EDGE_BOTTOM,MotionEvent.EDGE_LEFT,MotionEvent.EDGE_RIGHT};
 
  String szEvents[]={"ACTION_DOWN", "ACTION_MOVE",
  "ACTION_UP", "ACTION_MOVE", "ACTION_CANCEL", "ACTION_OUTSIDE",
  "ACTION_POINTER_DOWN","ACTION_POINTER_UP",
  "EDGE_TOP","EDGE_BOTTOM","EDGE_LEFT","EDGE_RIGHT"};
  for(int i=0; i < events.length; i++)
  {
   if(events[i] == event.getAction())
   {
    if(oldevent != event.getAction())
    {
     DisplayEventType(szEvents[i]);
     oldevent = event.getAction();
    }
    break;
   }
  }
  return super.onTouchEvent(event);
 }
 
2.2手勢識別
很多時候,一個好的用戶界面能夠吸引用戶的眼球。現在我們經常看到一些好的界面都帶有滑動、滾動等效果。但是觸摸屏是不可能產生滾動、滑動的消息的,需要根據其運動的軌跡用算法去判斷實現。在Android系統中,android.view.GestureDetector來實現手勢的識別,我們隻需要實現其GestureDetector.OnGestureListener接口來偵聽GestureDetector識別後的事件。我們需要在onTouchEvent,GestureDetector的onTouchEvent方法是進行軌跡識別。
代碼如下:
view plaincopy to clipboardprint?
import android.view.GestureDetector;  
import android.view.GestureDetector.OnGestureListener;  
public class TestEvent extends Activity {  
    /** Called when the activity is first created. */ 
      
    TextView    m_eventType;  
    int oldevent = -1;  
    private GestureDetector gestureDetector= new GestureDetector(new OnGestureListener()  
    {  
              
        // 鼠標按下的時候,會產生onDown。由一個ACTION_DOWN產生。  
        public boolean onDown(MotionEvent event) {  
              
            DisplayEventType("mouse down" + " " + event.getX() + "," + event.getY());  
            return false;  
        }  
        // 用戶按下觸摸屏、快速移動後松開,這個時候,你的手指運動是有加速度的。  
        // 由1個MotionEvent ACTION_DOWN,    
        // 多個ACTION_MOVE, 1個ACTION_UP觸發    
        // e1:第1個ACTION_DOWN MotionEvent    
        // e2:最後一個ACTION_MOVE MotionEvent    
        // velocityX:X軸上的移動速度,像素/秒    
        // velocityY:Y軸上的移動速度,像素/秒   
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,    
                float velocityY) {  
            DisplayEventType("onFling");  
            return false;  
        }  
        // 用戶長按觸摸屏,由多個MotionEvent ACTION_DOWN觸發    
        public void onLongPress(MotionEvent event) {  
            DisplayEventType("on long pressed");  
        }  
        // 滾動事件,當在觸摸屏上迅速的移動,會產生onScroll。由ACTION_MOVE產生  
        // e1:第1個ACTION_DOWN MotionEvent  
        // e2:最後一個ACTION_MOVE MotionEvent    
        // distanceX:距離上次產生onScroll事件後,X抽移動的距離  
        // distanceY:距離上次產生onScroll事件後,Y抽移動的距離  
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,    
                float distanceY) {  
            DisplayEventType("onScroll" + " " + distanceX + "," + distanceY);  
            return false;  
        }  
        //點擊瞭觸摸屏,但是沒有移動和彈起的動作。onShowPress和onDown的區別在於  
        //onDown是,一旦觸摸屏按下,就馬上產生onDown事件,但是onShowPress是onDown事件產生後,  
        //一段時間內,如果沒有移動鼠標和彈起事件,就認為是onShowPress事件。  
        public void onShowPress(MotionEvent event) {  
            DisplayEventType("pressed");  
              
        }  
        // 輕擊觸摸屏後,彈起。如果這個過程中產生瞭onLongPress、onScroll和onFling事件,就不會  
        // 產生onSingleTapUp事件。  
        public boolean onSingleTapUp(MotionEvent event) {  
            DisplayEventType("Tap up");  
            return false;  
        }  
          
    });  
      
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        m_eventType = (TextView)this.findViewById(R.id.eventtype);  
    }  
    @Override 
    public boolean onTouchEvent(MotionEvent event)  
    {  
        if(gestureDetector.onTouchEvent(event))  
            return true;  
        else 
            return false;  
    }  
      

import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
public class TestEvent extends Activity {
    /** Called when the activity is first created. */
 
 TextView  m_eventType;
 int oldevent = -1;
 private GestureDetector gestureDetector= new GestureDetector(new OnGestureListener()
    {
  
  // 鼠標按下的時候,會產生onDown。由一個ACTION_DOWN產生。
  public boolean onDown(MotionEvent event) {
  
   DisplayEventType("mouse down" + " " + event.getX() + "," + event.getY());
   return false;
  }
  // 用戶按下觸摸屏、快速移動後松開,這個時候,你的手指運動是有加速度的。
  // 由1個MotionEvent ACTION_DOWN, 
     // 多個ACTION_MOVE, 1個ACTION_UP觸發 
     // e1:第1個ACTION_DOWN MotionEvent 
     // e2:最後一個ACTION_MOVE MotionEvent 
     // velocityX:X軸上的移動速度,像素/秒 
     // velocityY:Y軸上的移動速度,像素/秒
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
             float velocityY) {
   DisplayEventType("onFling");
   return false;
  }
  // 用戶長按觸摸屏,由多個MotionEvent ACTION_DOWN觸發 
  public void onLongPress(MotionEvent event) {
   DisplayEventType("on long pressed");
  }
  // 滾動事件,當在觸摸屏上迅速的移動,會產生onScroll。由ACTION_MOVE產生
     // e1:第1個ACTION_DOWN MotionEvent
     // e2:最後一個ACTION_MOVE MotionEvent 
     // distanceX:距離上次產生onScroll事件後,X抽移動的距離
     // distanceY:距離上次產生onScroll事件後,Y抽移動的距離
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
             float distanceY) {
   DisplayEventType("onScroll" + " " + distanceX + "," + distanceY);
   return false;
  }
  //點擊瞭觸摸屏,但是沒有移動和彈起的動作。onShowPress和onDown的區別在於
  //onDown是,一旦觸摸屏按下,就馬上產生onDown事件,但是onShowPress是onDown事件產生後,
  //一段時間內,如果沒有移動鼠標和彈起事件,就認為是onShowPress事件。
  public void onShowPress(MotionEvent event) {
   DisplayEventType("pressed");
  
  }
  // 輕擊觸摸屏後,彈起。如果這個過程中產生瞭onLongPress、onScroll和onFling事件,就不會
  // 產生onSingleTapUp事件。
  public boolean onSingleTapUp(MotionEvent event) {
   DisplayEventType("Tap up");
   return false;
  }
    
    });
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        m_eventType = (TextView)this.findViewById(R.id.eventtype);
    }
 @Override
 public boolean onTouchEvent(MotionEvent event)
 {
  if(gestureDetector.onTouchEvent(event))
   return true;
  else
   return false;
 }
   
}
 
2.3鍵盤事件
鍵盤事件比較簡單,直接重寫原來的方法就可以瞭。
代碼如下:
view plaincopy to clipboardprint?
public boolean onKeyDown(int keyCode, KeyEvent event)   
    {  
        switch(keyCode)  
        {  
        case KeyEvent.KEYCODE_HOME:  
            DisplayEventType("Home down");  
            break;  
        case KeyEvent.KEYCODE_BACK:  
            DisplayEventType("Back down");  
            break;  
        case KeyEvent.KEYCODE_DPAD_LEFT:  
            DisplayEventType("Left down");  
            break;  
        }  
        //return true;  
        return super.onKeyDown(keyCode, event);  
    }  
    @Override 
    public boolean onKeyUp(int keyCode, KeyEvent event)   
    {  
        switch(keyCode)  
        {  
        case KeyEvent.KEYCODE_HOME:  
            DisplayEventType("Home up");  
            break;  
        case KeyEvent.KEYCODE_BACK:  
            DisplayEventType("Back up");  
            break;  
        case KeyEvent.KEYCODE_DPAD_LEFT:  
            DisplayEventType("Left up");  
            break;  
        }  
        //return true;  
        return super.onKeyUp(keyCode, event);  
    } 
public boolean onKeyDown(int keyCode, KeyEvent event)
 {
  switch(keyCode)
  {
  case KeyEvent.KEYCODE_HOME:
   DisplayEventType("Home down");
   break;
  case KeyEvent.KEYCODE_BACK:
   DisplayEventType("Back down");
   break;
  case KeyEvent.KEYCODE_DPAD_LEFT:
   DisplayEventType("Left down");
   break;
  }
  //return true;
  return super.onKeyDown(keyCode, event);
 }
 @Override
 public boolean onKeyUp(int keyCode, KeyEvent event)
 {
  switch(keyCode)
  {
  case KeyEvent.KEYCODE_HOME:
   DisplayEventType("Home up");
   break;
  case KeyEvent.KEYCODE_BACK:
   DisplayEventType("Back up");
   break;
  case KeyEvent.KEYCODE_DPAD_LEFT:
   DisplayEventType("Left up");
   break;
  }
  //return true;
  return super.onKeyUp(keyCode, event);
 }
 
3. 模擬鼠標/按鍵事件
 
Instrumentation發送鍵盤鼠標事件:Instrumentation提供瞭豐富的以send開頭的函數接口來實現模擬鍵盤鼠標,如下所述:
sendCharacterSync(int keyCode)            //用於發送指定KeyCode的按鍵
sendKeyDownUpSync(int key)                //用於發送指定KeyCode的按鍵
sendPointerSync(MotionEvent event)     //用於模擬Touch
sendStringSync(String text)                   //用於發送字符串
 
    Instrumentation inst=new Instrumentation();
                     inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 10, 10, 0));
                     inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 10, 10, 0));

作者“guozhenqian”
 

發佈留言