凡是涉及到UI編程,就必然需要進行各種事件處理。
Android提供了兩套事件處理機制:
1.基於監聽的事件處理。
2.基於回調的事件處理。
基於監聽的事件處理就是在android的組件上綁定特定的監聽器,而基於回調的事件處理就是重寫UI組件或者Activity的回調方法。
基於回調的事件處理用於處理一些具有通用性的事件,基於監聽的事件處理用於處理與具體業務相關的事件。
事件處理模型
事件處理模型中,主要涉及三類對象:
1.EventSource(事件源)。事件發生的場所,通常就是各個組件,比如按鈕、窗口、菜單。
2.Event(事件)。事件封裝了事件發生的相關信息。
3.EventListener(事件監聽器)。監聽事件源發生的事件,並對事件作出相應的響應。
基於回調的事件處理模型就是將EventSource和EventListener合二爲一了,即事件源也是事件監聽器(處理器)。
下面通過一個例子演示兩種事件處理模型。
Activity類:
package com.zzj.ui.eventhandledemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import com.zzj.ui.R;
public class EventHandleActivity extends Activity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.event_handle_activity);
editText = (EditText) findViewById(R.id.editText1);
editText.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
System.out.println("EditText.onKeyDown --> "
+ ((EditText) v).getText());
} else if (event.getAction() == KeyEvent.ACTION_UP) {
System.out.println("EditText.onKeyUp --> "
+ ((EditText) v).getText());
}
return false;
}
});
}
}
重寫EditText:package com.zzj.ui.eventhandledemo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
System.out.println("MyEditText.onKeyDown --> "
+ this.getText().toString());
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
System.out.println("MyEditText.onKeyUp --> "
+ this.getText().toString());
return super.onKeyUp(keyCode, event);
}
}
佈局文件:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="input"
android:inputType="text" >
</EditText>
<com.zzj.ui.eventhandledemo.MyEditText
android:id="@+id/myEditText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="input"
android:inputType="text" />
</LinearLayout>
界面:
運行程序,在兩個輸入框中分別輸入abc,查看日誌:
可以看到,基於監聽的事件處理和基於回調的事件處理達到了相同的效果。
需要注意的是,以上事件處理,只對硬鍵盤有效,對軟鍵盤無效。
另外,基於回調的事件處理代碼簡潔,但不能訪問外圍類的資源;而基於監聽的事件處理,可以把監聽器作爲內部類而存在,這樣就可以訪問外圍類的資源了。
基於監聽的事件處理是一種委派式(Delegation)的事件處理方式。UI組件(事件源)將發生的事件委派給特定的對象(監聽器)處理,這很類似於人類社會的分工協作。例如某商場發生火災時,商場並不會處理該事件,而是交給消防局處理;商場發生鬥毆事件時,就交給公安局處理。商場可以將不同的事件委派給不同的機構處理,同時消防局和公安局也可以對各種場所進行監聽並且處理髮生的事件。這種委派式的事件處理方式將事件源和監聽器分離,能提高程序的可維護性。