Android 事件处理

来源:互联网 发布:怪物猎人捏脸数据萌妹 编辑:程序博客网 时间:2024/06/06 07:31

Android 事件处理

--学习笔记2(金海建)

目的:通过全面的分析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));

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 网页显示代理服务器连接失败怎么办 墙内线路断了怎么办 墙里的电线坏了怎么办 鱼竿最前端断了怎么办 下雨天墙壁与管道间漏水怎么办 电饭锅的电线被雨淋了怎么办 钢琴跨八度手短怎么办 弹钢琴手指不灵活怎么办呢? 理发剪不锋利了怎么办 室外宽带线断了怎么办 接宽带光纤太短怎么办 装修光纤网线太短怎么办 宽带入户线断了怎么办 电信有无线没网怎么办 墙里的网线断了怎么办 墙里网线断了怎么办 3根网线断了怎么办 剪了层次的头发怎么办 小米6充电线坏了怎么办 小米6导航信号弱怎么办 麦多多充不了电怎么办 一加数据线坏了怎么办 小米耳机泡水了怎么办 公司拖欠工资公司破产了怎么办 苹果x外壳掉漆怎么办 手机壳按键很硬怎么办 棉质白衣服染色怎么办 白棉t恤混洗染色怎么办 包包被衣服染色了怎么办 白色衣服染了菜汁怎么办 一加3t屏幕刺眼怎么办 怀孕吃了好多杏怎么办 门破了个洞怎么办 钢圈轮毂刮花了怎么办 瓷砖用刀子划了怎么办 陶瓷洗手台裂了怎么办 洗车泵水管坏了怎么办 印胶浆里面渗入了发泡浆怎么办? 管子断在水管里怎么办 衣服上的织带缩水怎么办 真丝衣服拔缝了怎么办