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(事件監聽器):扶着監聽事件源所發生的事件,并對各種事件做出相應的響應。
事件處理流程示意圖如下:
内部類可以作為事件監聽器類,如果某個監聽器要被多個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都囊括了,這隻是幾個比較典型的例子,效果如下:
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);
效果與上圖類似,隻是文字不一樣
5. 觸摸屏事件,當用手或者用筆在觸摸屏上做動作是發生,相關代碼如下:
public boolean ontouchevent(motionevent event)
int iaction=event.getaction();
if(iaction==motionevent.action_move)
displaytoast("你在觸摸屏上進行了滑動");
else
return false;
return super.ontouchevent(event);
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