Android基於監聽的事件處理機制
Android提供了強大的事件處理機制,主要包括兩大類:
1,基於監聽的事件處理機制:主要做法是為Android介面組件綁定特定的事件監聽器
2,基於回調的事件處理機制:主要做法是重寫Android組件特定的回調方法,或重寫Activity的回調方法。也就是說Android的絕大多數的介面組件都提供了事件響應的回調方法,開發人員只要重寫它們即可
基於監聽的事件處理是一種更加物件導向的事件處理,這種事件處理方式與Java的Swing處理方式幾乎相同。
監聽處理模型:
事件來源(Event Source):事件發生的場所,就是各個組件,比如按鈕,視窗,菜單等
事件(Event):事件封裝了介面組件上發生的特定事情(就是使用者操作)。如果程式需要獲得介面組件上所發生事件的相關資訊,一般通過Event對象來擷取
事件監聽器(Event Listener):負責監聽事件來源所發生的時間,並且對各個事件作出響應。
委派式事件處理方法:
普通組件(事件來源)將整個事件處理委派給特定的對象(事件監聽器);當該事件來源發生指定的時間是,就通知所委派的事件監聽器來處理這個事件。
每個組件都可以針對特定的時間指定一個事件監聽器,每個事件監聽器也可以監聽一個或多個事件來源。因為同一個事件來源上可能發生多個事件,委派式事件處理方式可以吧事件來源上所有可能發生的時間分別授權給不同的事件處理器來處理;同時也可以讓一類事件都使用同一個事件監聽器來處理。
activity_main.xml
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--><linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal"><edittext android:id="@+id/txt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:editable="false" android:cursorvisible="false" android:textsize="12pt"><!--{cke_protected}{C}%3C!%2D%2D%20%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E6%8C%89%E9%92%AE%EF%BC%8C%E8%AF%A5%E6%8C%89%E9%92%AE%E5%B0%86%E4%BD%9C%E4%B8%BA%E4%BA%8B%E4%BB%B6%E6%BA%90%20%2D%2D%3E--><button android:id="@+id/bn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="單擊我"></button></edittext></linearlayout>MainActivity.java
public class MainActivity extends Activity{@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取應用程式中的bn按鈕Button bn = (Button) findViewById(R.id.bn);// 為按鈕綁定事件監聽器。bn.setOnClickListener(new MyClickListener()); // ①}// 定義一個單擊事件的監聽器class MyClickListener implements View.OnClickListener{// 實現監聽器類必須實現的方法,該方法將會作為事件處理器@Overridepublic void onClick(View v){EditText txt = (EditText) findViewById(R.id.txt);txt.setText("bn按鈕被單擊了!");}}}基於監聽器的事件處理模型的編程步驟如下:
1,擷取普通介面組件(事件來源),也就是被監聽的對象
2,實現時間監聽類,該監聽器類是一個特殊的Java類,必須實現一個XxxListener介面
3,呼叫事件源的setXXXListener方法,將事件監聽器對象註冊給普通組件(事件來源)
事件監聽器必須實現事件監聽介面,Android的不同介面組件提供了不同的監聽器介面,這些介面通常以內部類的形式存在。以View類為例,包含如下監聽介面:
View.OnClickListener單擊事件的事件監聽器必須時間的介面
View.OnCreateContextMenuListener:建立操作功能表時間的事件監聽器必須實現的介面
View.onFocusChangeListener:焦點改變事件的事件監聽器必須實現的介面
View.OnKeyListener:按鍵事件的時間監聽器必須實現的介面
所謂事件監聽器,其實就是實現了特定介面的java類的執行個體。在程式上一般有幾種形式:
1,內部類形式:將事件監聽器定義成當前類的內部類
public class EventQs extends Activity{@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取應用程式中的bn按鈕Button bn = (Button) findViewById(R.id.bn);// 為按鈕綁定事件監聽器。bn.setOnClickListener(new MyClickListener()); // }// 定義一個單擊事件的監聽器,內部類形式class MyClickListener implements View.OnClickListener{// 實現監聽器類必須實現的方法,該方法將會作為事件處理器@Overridepublic void onClick(View v){EditText txt = (EditText) findViewById(R.id.txt);txt.setText("bn按鈕被單擊了!");}}}
因為監聽器是內部類,所以可以自由訪問外部類的所有介面組件,這也是內部類的優勢。
2,外部類形式:將事件監聽器類定義成一個外部類
外部類形式的事件監聽器不能自由訪問建立GUI介面類的組件,使用時需要向監聽器類傳遞GUI介面類的組件的引用 ,所以用的比較少
MainActivity.java
public class MainActivity extends Activity{EditText address;EditText content;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 擷取頁面中收件者地址、簡訊內容address = (EditText)findViewById(R.id.address);content = (EditText)findViewById(R.id.content);Button bn = (Button)findViewById(R.id.send);bn.setOnLongClickListener(new SendSmsListener(this , address, content));//外部類形式,需要傳遞本類組件}}SendSmsListener.java
public class SendSmsListener implements OnLongClickListener{private Activity act;private EditText address;private EditText content;public SendSmsListener(Activity act, EditText address, EditText content){this.act = act;this.address = address;this.content = content;}@Overridepublic boolean onLongClick(View source){String addressStr = address.getText().toString();String contentStr = content.getText().toString();// 擷取簡訊管理器SmsManager smsManager = SmsManager.getDefault();// 建立傳送簡訊的PendingIntentPendingIntent sentIntent = PendingIntent.getBroadcast(act, 0, new Intent(), 0);// 發送文本簡訊smsManager.sendTextMessage(addressStr, null, contentStr, sentIntent, null);Toast.makeText(act, "簡訊發送完成", Toast.LENGTH_LONG).show();return false;}}
3,Activity本身作為事件監聽器類:讓Activity本身實現監聽介面,並實現事件處理器方法
// Activity實現事件監聽器介面public class ActivityListener extends Activityimplements OnClickListener{EditText show;Button bn;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);show = (EditText) findViewById(R.id.show);bn = (Button) findViewById(R.id.bn);// 直接使用Activity作為事件監聽器bn.setOnClickListener(this);}// 實現事件處理方法@Overridepublic void onClick(View v){show.setText("bn按鈕被單擊了!");}}
4,匿名內部類形式:使用匿名內部類建立事件監聽器對象。代碼簡單的情況,只能用一次
public class MainActivity extends Activity{EditText show;Button bn;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);show = (EditText) findViewById(R.id.show);bn = (Button) findViewById(R.id.bn);// 直接使用Activity作為事件監聽器bn.setOnClickListener(new OnClickListener(){// 實現事件處理方法@Overridepublic void onClick(View v){show.setText("bn按鈕被單擊了!");}});}