Android平臺的事件處理機制有兩種
基於回調機制的事件處理:Android平臺中,每個View都有自己的處理事件的回調方法,開發人員可以通過重寫View中的這些回調方法來實現需要的響應事件。
基於監聽接口的事件處理:面向對象設計中的主流處理方式,采用委托事件處理的方式,將發生的事件委托給註冊過的事件監聽器來處理.
1.基於回調機制的事件處理:重寫android組件特定的一些回調方法
onKeyDown()/ onKeyUp(),該方法是接口KeyEvent.Callback中的抽象方法,所有的View全部實現瞭該接口並重寫瞭該方法,該方法用來捕捉手機鍵盤被按下的事件。public boolean onKeyDown (int keyCode, KeyEvent event)
onTouchEvent(),該方法在View類中的定義,並且所有的View子類全部重寫瞭該方法,應用程序可以通過該方法處理手機屏幕的觸摸事件。
public booleanonTouchEvent (MotionEvent event)
onFocusChanged(),隻能在View中重寫。該方法是焦點改變的回調方法,當某個控件重寫瞭該方法後,當焦點發生變化時,會自動調用該方法來處理焦點改變的事件。protected void onFocusChanged (boolean gainFocus, int direction, Rect previouslyFocusedRect)
2.基於監聽接口的事件處理:為android組件綁定特定的事件監聽器.事件監聽器是視圖View類的接口,包含一個單獨的回調方 法。這些方法將在視圖中註冊的監聽器被用戶界面操作觸發時由Android框架調用。下面這些回調方法被包含在事件監聽器接口中:
onClick():包含於View.OnClickListener。當用戶觸摸這個item(在觸摸模式下),或者通過瀏覽鍵或跟蹤球聚焦在這個item上,然後按下“確認”鍵或者按下跟蹤球時被調用。
onLongClick():包含於View.OnLongClickListener。當用戶觸摸並控制住這個item(在觸摸模式下),或者通過瀏覽鍵或跟蹤球聚焦在這個item上,然後保持按下“確認”鍵或者按下跟蹤球(一秒鐘)時被調用。
onFocusChange():包含於View.OnFocusChangeListener。當用戶使用瀏覽鍵或跟蹤球瀏覽進入或離開這個item時被調用。
onKey() :包含於View.OnKeyListener。當用戶聚焦在這個item上並按下或釋放設備上的一個按鍵時被調用。
onTouch() :包含於View.OnTouchListener。當用戶執行的動作被當做一個觸摸事件時被調用,包括按下,釋放,或者屏幕上任何的移動手勢(在這個item的邊界內)。
onCreateContextMenu() :包含於View.OnCreateContextMenuListener。當正在創建一個上下文菜單的時候被調用(作為持續的“長點擊”動作的結果)。
Android系統界面事件的傳遞和處理規則
如果界面控件設置瞭事件監聽器,則事件將先傳遞給事件監聽器
如果界面控件沒有設置事件監聽器,界面事件則會直接傳遞給界面控件的其他事件處理函數
即使界面控件設置瞭事件監聽器,界面事件也可以再次傳遞給其他事件處理函數
是否繼續傳遞事件給其他處理函數是由事件監聽器處理函數的返回值決定的
如果監聽器處理函數的返回值為true,表示該事件已經完成處理過程,不需要其他處理函數參與處理過程,這樣事件就不會再繼續進行傳遞
如果監聽器處理函數的返回值為false,則表示該事件沒有完成處理過程,或需要其他處理函數捕獲到該事件,事件會被傳遞給其他的事件處理函數
基於監聽接口的事件處理例子
在智能手機上,很多應用軟件需要得到用戶手指操作的時候的坐標和一些用戶的操作,鑒於開發Android經常會用到滑動的地方,所以下面敘述一下滑動的例子:
效果圖:
<span style="font-size:16px;">activity類代碼:
package com.TouchView;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class TouchViewActivity extends Activity {
private TextView eventlable;
private TextView histroy;
private TextView TouchView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TouchView = (TextView) findViewById(R.id.touch_area);
histroy = (TextView) findViewById(R.id.history_label);
eventlable = (TextView) findViewById(R.id.event_label);
TouchView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
// 當按下的時候
case (MotionEvent.ACTION_DOWN):
Display("ACTION_DOWN", event);
break;
// 當按上的時候
case (MotionEvent.ACTION_UP):
int historysize = ProcessHistory(event);
histroy.setText("歷史數據" + historysize);
Display("ACTION_UP", event);
break;
// 當觸摸的時候
case (MotionEvent.ACTION_MOVE):
Display("ACTION_MOVE", event);
}
return true;
}
});
}
public void Display(String eventType, MotionEvent event) {
// 觸點相對坐標的信息
int x = (int) event.getX();
int y = (int) event.getY();
// 表示觸屏壓力大小
float pressure = event.getPressure();
// 表示觸點尺寸
float size = event.getSize();
// 獲取絕對坐標信息
int RawX = (int) event.getRawX();
int RawY = (int) event.getRawY();
String msg = "";
msg += "事件類型" + eventType + "\n";
msg += "相對坐標" + String.valueOf(x) + "," + String.valueOf(y) + "\n";
msg += "絕對坐標" + String.valueOf(RawX) + "," + String.valueOf(RawY)
+ "\n";
msg += "觸點壓力" + String.valueOf(pressure) + ",";
msg += "觸點尺寸" + String.valueOf(size) + "\n";
eventlable.setText(msg);
}
public int ProcessHistory(MotionEvent event) {
int history = event.getHistorySize();
for (int i = 0; i < history; i++) {
long time = event.getHistoricalEventTime(i);
float pressure = event.getHistoricalPressure(i);
float x = event.getHistoricalX(i);
float y = event.getHistoricalY(i);
float size = event.getHistoricalSize(i);
}
return history;
}
}
</span>
<span style="font-size:16px;">activity類代碼:
package com.TouchView;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class TouchViewActivity extends Activity {
private TextView eventlable;
private TextView histroy;
private TextView TouchView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TouchView = (TextView) findViewById(R.id.touch_area);
histroy = (TextView) findViewById(R.id.history_label);
eventlable = (TextView) findViewById(R.id.event_label);
TouchView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
// 當按下的時候
case (MotionEvent.ACTION_DOWN):
Display("ACTION_DOWN", event);
break;
// 當按上的時候
case (MotionEvent.ACTION_UP):
int historysize = ProcessHistory(event);
histroy.setText("歷史數據" + historysize);
Display("ACTION_UP", event);
break;
// 當觸摸的時候
case (MotionEvent.ACTION_MOVE):
Display("ACTION_MOVE", event);
}
return true;
}
});
}
public void Display(String eventType, MotionEvent event) {
// 觸點相對坐標的信息
int x = (int) event.getX();
int y = (int) event.getY();
// 表示觸屏壓力大小
float pressure = event.getPressure();
// 表示觸點尺寸
float size = event.getSize();
// 獲取絕對坐標信息
int RawX = (int) event.getRawX();
int RawY = (int) event.getRawY();
String msg = "";
msg += "事件類型" + eventType + "\n";
msg += "相對坐標" + String.valueOf(x) + "," + String.valueOf(y) + "\n";
msg += "絕對坐標" + String.valueOf(RawX) + "," + String.valueOf(RawY)
+ "\n";
msg += "觸點壓力" + String.valueOf(pressure) + ",";
msg += "觸點尺寸" + String.valueOf(size) + "\n";
eventlable.setText(msg);
}
public int ProcessHistory(MotionEvent event) {
int history = event.getHistorySize();
for (int i = 0; i < history; i++) {
long time = event.getHistoricalEventTime(i);
float pressure = event.getHistoricalPressure(i);
float x = event.getHistoricalX(i);
float y = event.getHistoricalY(i);
float size = event.getHistoricalSize(i);
}
return history;
}
}
</span>
main.xml代碼部分:
[html] <span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/touch_area"
android:layout_width="fill_parent"
android:layout_height="300dip"
android:background="#0FF"
android:textColor="#FFFFFF"
android:text="觸摸事件測試區"
/>
<TextView
android:id="@+id/history_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="歷史數據"
/>
<TextView
android:id="@+id/event_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="觸摸事件:"
/>
</LinearLayout>
</span>
摘自 北京大學-Google Android實驗室