天天看點

【Android】 Android 事件處理

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)方法後,就可以處理簡單的觸摸屏事件。

代碼如下:

[java] view plaincopy

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方法是進行軌迹識别。

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");  

        // 使用者長按觸摸屏,由多個motionevent action_down觸發    

        public void onlongpress(motionevent event) {  

            displayeventtype("on long pressed");  

        // 滾動事件,當在觸摸屏上迅速的移動,會産生onscroll。由action_move産生  

        // e1:第1個action_down motionevent  

        // distancex:距離上次産生onscroll事件後,x抽移動的距離  

        // distancey:距離上次産生onscroll事件後,y抽移動的距離  

        public boolean onscroll(motionevent e1, motionevent e2, float distancex,    

                float distancey) {  

            displayeventtype("onscroll" + " " + distancex + "," + distancey);  

        //點選了觸摸屏,但是沒有移動和彈起的動作。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");  

    });  

    @override  

    public void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.main);  

        m_eventtype = (textview)this.findviewbyid(r.id.eventtype);  

    public boolean ontouchevent(motionevent event)  

        if(gesturedetector.ontouchevent(event))  

            return true;  

        else  

}  

2.3鍵盤事件

鍵盤事件比較簡單,直接重寫原來的方法就可以了。

public boolean onkeydown(int keycode, keyevent event)   

        switch(keycode)  

        case keyevent.keycode_home:  

            displayeventtype("home down");  

            break;  

        case keyevent.keycode_back:  

            displayeventtype("back down");  

        case keyevent.keycode_dpad_left:  

            displayeventtype("left down");  

        //return true;  

        return super.onkeydown(keycode, event);  

    public boolean onkeyup(int keycode, keyevent event)   

            displayeventtype("home up");  

            displayeventtype("back up");  

            displayeventtype("left up");  

        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));

android提供了強大的事件處理機制,它包括兩套處理機制:

1.基于監聽的事件處理

2.基于回調的事件處理

對于android基于監聽的事件處理,主要的做法是為android界面元件綁定特定的事件監聽器。

對于android基于回調的事件處理,主要的方法是重寫android元件特定的回調方法或者重寫

activity的回調方法

一、基于監聽的事件處理

    在事件監聽的處理模型中,主要涉及如下三類對象:

1.event source(事件源):事件發生的場所,通常就是各個元件、例如按鈕、視窗、菜單等。

2.event(事件):事件封裝了界面元件上發生的特定事情(通常就是一次使用者操作)。

3.event listener(事件監聽器):扶着監聽事件源所發生的事件,并對各種事件做出相應的響應。

    事件處理流程示意圖如下:

【Android】 Android 事件處理

    内部類可以作為事件監聽器類,如果某個監聽器要被多個gui界面所共享我們可以使用外部類

作為事件監聽器類,還有一種是匿名内部類作為事件監聽器類,這裡就不詳細介紹了。

    android還中還有一種更簡單的綁定事件監聽器的方式,直接在界面布局中為指定的标簽綁定事件處理方法。

如:android:onclick="clickhandler",這樣就意味着開發者需要在該界面布局對應的activity中定義一個void clickhandler(view source),該方法将會處理該按鈕上的單擊事件。

下面我們來看一段 java代碼:

[java] 

public class ex003_01activity extends activity {  

    /** called when the activity is first created. */  

    @override  

    public void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.main);  

        //定義一個事件的處理方法  

        //輕重source參數代表事件源  

        public void clickhandler(view source){  

            textview show=(textview)findviewbyid(r.id.tv);  

            show.settext("bn按鈕被點選了");  

        }  

    }  

}  

二、基于回調事件處理

    從代碼的實作的角度來看,基于回調的事件處理模型更加簡單。如果說事件監聽制是一種委托式的事件處理,那麼回調機制恰好與之相反:對于基于回調機制的事件處理模型來說,事件源與事件監聽器是統一的。為了使用回調機制類處理gui元件上所發生的事件,我們需要為該元件提供對應的事件處理方法--而java又是一種靜态語言,我們無法為某個對象動态的添加方法,是以隻能繼承gui元件類,并重寫該元件類的事件處理方法來實作。

為了實作回調機制的事件處理, android為所有的gui 元件都提供了一些事件處理的回調方法,以view為例,該類包含如下方法:

boolean onkeydown(int keycode,keyevent event):當使用者在該元件上按下某個鍵時觸發的方法。

boolean onkeylongpress(int keycode,keyevent event):當使用者在該元件上長按某個按鈕時觸發該方法。

boolean onkeyshortcut(int keycode,keyevent event): 當一個快捷鍵事件發生時觸發該放過。

boolean onkeyup(int keycode,keyevent event):當使用者在該元件上松開某個按鍵時觸發該方法

boolean ontouchevent(motionevent event):當使用者在該元件上觸發觸摸屏事件時觸發該方法。

boolean ontrackballeventi(motionevent event):當使用者在該元件上觸發軌迹球屏事件時觸發該事件。

下面我們來看一段代碼:

public class mybutton extends button  

{  

    public mybutton(context context , attributeset set)  

    {  

        super(context , set);  

        // todo auto-generated constructor stub  

    public boolean onkeydown(int keycode, keyevent event)  

        super.onkeydown(keycode , event);  

        log.v("-crazyit.org-" , "the onkeydown in mybutton");  

        //傳回true,表明該事件不會向外擴散  

        return true;  

上面的代碼我們重寫了button類的onkeydown(int keycode,keyevent event)方法,該方法将會負責處理按鈕上的鍵盤事件。

基于回調的事件傳播

    幾乎所有的基于回調的事件處理方法都有一個boolean類型的傳回值,該傳回值用于辨別該處理方法是否能完全處理該事件:

1.如果傳回true,則表明該處理方法已完全處理了該事件,該事件不會被傳播出去。

2.如果傳回false,表明該處理方法未完全處理該事件,該事件會傳播出去。

    對于基于回調的事件處理傳播而言,某元件上所發生的事情不僅激發該元件上的回調方法,也會觸發該元件所在的activity的回調方法——隻要事件能傳播到該activity。

參考網址:http://www.2cto.com/kf/201302/190400.html

(一) 事件使我們在于ui互動式發生的,我們點選一個按鍵時,可能就已經除非好幾個事件,例如我們點選數字鍵“0”,他會涉及到按下事件,和一個彈起(松開)事件,在我們android中還可能涉及到觸摸屏事件,是以在android系統中,事件是作為常用的功能之一;

在android下,事件的發生是在監聽器下進行,android系統可以響應按鍵事件和觸摸屏事件,事件說明如下:

l onclick(view v) 一個普通的點選按鈕事件

l boolean onkeymultiple(int keycode,int repeatcount,keyevent event)用于在多個事件連續時發生,用于按鍵重複,必須重載@override實作

l boolean onkeydown(int keycode,keyevent event) 用于在按鍵進行按下時發生

l boolean onkeyup(int keycode,keyevent event) 用于在按鍵進行釋放時發生

l ontouchevent(motionevent event)觸摸屏事件,當在觸摸屏上有動作時發生

l boolean onkeylongpress(int keycode, keyevent event)當你長時間按時發生(疑問?)

(二) 首先我們建立一個android項目,當項目建立好之後,直接在預設的main.xml檔案中拖放一個button 按鈕,其他的不需要在這裡做什麼了,然後就可以到命名好的.java檔案中進行先關代碼的書寫;

1.     對要使用的控件進行引用,當然你也可以用到的時候再在相關類控件添加引用

import android.app.activity;

import android.os.bundle;

import android.view.keyevent;

import android.view.motionevent;

import android.view.view;

import android.widget.button;

import android.widget.toast;

2.     獲得相關對象,設定控件監聽器

button button=(button) findviewbyid(r.id.button1);

        //設定監聽

        button.setonclicklistener(new button.onclicklistener()

        {

           @override

           public void onclick(view v) {

              // todo auto-generated method stub

              displaytoast("事件觸發成功");

           }           

        });

請注意這裡末尾使用的是分号“;這裡就是獲得button的執行個體,然後對他進行監聽,當使用者點選時就會發生onclick事件,這裡還用到一個方法,就是顯示一個短消息,在螢幕停留幾秒鐘就會自動消失,其方法如下:

public void displaytoast(string str)

    {

    toast.maketext(this, str, toast.length_short).show();

    }

當然你也可以設定顯示長點,即toast.length_short改為toast.length_long

3.     當按鍵按下是發生的事件

public boolean onkeydown(int keycode,keyevent event)

    switch(keycode)

    case keyevent.keycode_0:

        displaytoast("你按下數字鍵0");

        break;

    case keyevent.keycode_dpad_center:

        displaytoast("你按下中間鍵");

        break;sss

    case keyevent.keycode_dpad_down:

        displaytoast("你按下下方向鍵");

    case keyevent.keycode_dpad_left:

        displaytoast("你按下左方向鍵");

    case keyevent.keycode_dpad_right:

        displaytoast("你按下右方向鍵");

    case keyevent.keycode_dpad_up:

        displaytoast("你按下上方向鍵");

           break;

    case keyevent.keycode_alt_left:

        displaytoast("你按下組合鍵alt+←");

    return super.onkeydown(keycode, event);

這裡所有的keycode都囊括了,這隻是幾個比較典型的例子,效果如下:

【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理

4.         當按鍵彈起時發生的事件,代碼如下:

public boolean onkeyup(int keycode,keyevent event)

    switch(keycode)

    case keyevent.keycode_0:

        displaytoast("松開數字鍵0");

        break;

    case keyevent.keycode_dpad_center:

        displaytoast("松開中間鍵");

    case keyevent.keycode_dpad_down:

        displaytoast("松開下方向鍵");

    case keyevent.keycode_dpad_left:

        displaytoast("松開左方向鍵");

    case keyevent.keycode_dpad_right:

        displaytoast("松開右方向鍵");

    case keyevent.keycode_dpad_up:

        displaytoast("松開上方向鍵");

           break;

    case keyevent.keycode_alt_left:

        displaytoast("松開組合鍵alt+←");

    return super.onkeyup(keycode, event);

效果與上圖類似,隻是文字不一樣

【Android】 Android 事件處理

5.         觸摸屏事件,當用手或者用筆在觸摸屏上做動作是發生,相關代碼如下:

public boolean ontouchevent(motionevent event)

    int iaction=event.getaction();

    if(iaction==motionevent.action_move)

        displaytoast("你在觸摸屏上進行了滑動");

    else

        return false;

    return super.ontouchevent(event);

【Android】 Android 事件處理

6.         連續點選按鍵時發生的事件

publicboolean onkeymultiple(int keycode,int repeatcount,keyevent event)

{

 return super.onkeymultiple(keycode, repeatcount, event);

}

 整體效果還不錯,又向android邁進一步!!! 源碼下載下傳

作者: 神舟龍

    

出處: javascript:void(0)

參考網址:javascript:void(0)archive/2011/03/09/1977760.html

【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理
【Android】 Android 事件處理