android(基於監聽)的事件處理

    

     基於監聽的事件模型分工更明確,事件源、事件監聽由兩個類分開,因此具有更好的可維護性。

    Android的事件處理機制保證基於監聽的事件監聽器會被優先出發。


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

    1.Event Source(事件源):事件發生的場所,通常就是各個組件,例如按鈕,窗口,菜單等。

    2.Event(事件):事件封裝了界面組件上發生的特定事情(通常就是一次用戶操作)。如果程序需要獲得界面組件上所發生事情的相關信息,一般通過Event對象來取得。

    3.Event Listener(事件監聽器):負責監聽事件源所發生的事件,並對各種事件做出相應的響應。


wKiom1YTtOvwtKnPAAMAFK_9leM164.jpg

    

    Android爲不同的界面組件提供了不同的監聽器接口:

    1.View.OnClickListener:單擊事件的事件監聽器必須實現的接口。

    2.View.OnCreateContextMenuListener:創建上下文菜單事件的事件監聽器必須實現的接口。

    3.View.onFocusChangeListener:焦點改變事件的事件監聽器必須實現的接口。

    4.View.OnKeyListener:按鍵事件的事件監聽器必須實現的接口。

    5.View.OnLongClickListener:長按事件的事件監聽器必須實現的接口。

    6.View.OnTouchListener:觸摸事件的事件監聽器必須實現的接口。


    所謂的事件監聽器,其實就是實現了特定接口的java類的實例。在程序中實現事件監聽器,通常有如下幾種形式。

    1.內部類形式:將事件監聽器類定義成當前的內部類。

    2.外部類形式:將事件監聽器類定義成一個外部類。

    3.Activity本身作爲事件監聽器類:讓Activity本身實現監聽器接口,並實現事件處理方法。

    4.匿名內部類形式:使用匿名內部類創建事件監聽器對象。

    5.直接綁定標籤:爲UI組件的android:onClick屬性指定事件的監聽方法,開發者需要在Activity中定義該事件監聽方法(該方法必須有一個View類型的形參,該形參代表被單擊的UI組件),當用戶單擊該UI組件時,系統將會激發android:onClick屬性所指定的方法。



    1.內部類作爲事件監聽器類

    使用內部類作爲事件監聽器類的優勢:

    ①使用內部類可以在當前類中複用該監聽器類

    ②因爲監聽器類是外部類的內部類,所以可以自由訪問外部類的所有界面組件。


示例:

activity_main.xml   

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="內部類做爲事件監聽器類" />

</LinearLayout>


MainActivity.java

package com.example.neibulei;
public class MainActivity extends Activity {

	private Button bn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 獲取activity_main界面中的id爲bn按鈕
		bn = (Button) findViewById(R.id.bn);
		// 爲bn按鈕綁定點擊事件監聽器
		bn.setOnClickListener(new MyClickListener());
	}
	
	// 定義一個單擊事件監聽器
	class MyClickListener implements View.OnClickListener {
		@Override
		// 實現監聽器類必須實現的方法,該方法將會作爲事件處理器
		public void onClick(View v) {
			// TODO Auto-generated method stub
			//事件處理器做出的響應
			Toast.makeText(MainActivity.this, "內部類做爲事件監聽器類", 1).show();
		}
	}
}



    2.外部類作爲事件監聽器類

    外部類作爲事件監聽器類的劣勢:

    ①事件監聽器通常屬於特定的GUI界面,定義成外部類不利於提高程序的內聚性。

    ②外部類形式的事件監聽器不能自由訪問GUI界面的類中的組件,變成不夠簡潔。

    

    外部類作爲事件監聽器類的優勢:

    如果某個事件監聽器確實需要被多個GUI界面所共享,而且主要是完成某種業務邏輯的實現,則可以考慮使用外部類的形式來定義事件監聽器類。

示例:

activity_main.xml 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/address"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/bn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="外部類作爲事件監聽器類(發送短信)" />

</LinearLayout>


MainActivity.java

package com.example.waibulei;

public class MainActivity extends Activity {
	EditText address; // 短信發送給這個號碼
	EditText content; // 短信內容
	Button bn; // 發送按鈕

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 獲取頁面內中的收件人地址、短信內容
		address = (EditText) findViewById(R.id.address);
		content = (EditText) findViewById(R.id.content);
		bn = (Button) findViewById(R.id.bn);
		// 爲bn按鈕綁定長按事件監聽器
		bn.setOnLongClickListener(new SendSmsListener(this, address, content));
	}
}


SendSmsListener.java

package com.example.waibulei;

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

	@Override
	public boolean onLongClick(View v) {
		// 取出號碼與短信內容
		String addressStr = address.getText().toString().trim();
		String contentStr = content.getText().toString().trim();
		// 獲取短信管理器
		SmsManager smsManager = SmsManager.getDefault();
		// 發送文本短信
		smsManager.sendTextMessage(addressStr, null, contentStr, null, null);
		return false;
	}

}

在AndroidManifest.xml上添加發送短信的權限

<uses-permission android:name="android.permission.SEND_SMS" />

  


 3.Activity本身作爲事件監聽器 

    Activity本身作爲事件監聽器的劣勢:

    ①這種形式可能造成程序結構混亂,Activity的主要職責應該是完成界面初始化工作,但此時還需要包含事件處理器的方法,從而引起混亂。

    ②如果Activity界面類需要實現監聽器接口,讓人感覺比較怪異。


     Activity本身作爲事件監聽器的優勢:

    直接在Activity類中定義事件處理方法,非常簡潔。

示例:

activity_main.xml 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:orientation="vertical"
 >

    <Button
        android:id="@+id/bn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activity本身作爲事件監聽器" />

</LinearLayout>


MainActivity.java

package com.example.activitybenshen;

//實現事件監聽器接口
public class MainActivity extends Activity implements OnClickListener {
	private Button bn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		bn = (Button) findViewById(R.id.bn);
		// 直接使用Activity作爲監聽器
		bn.setOnClickListener(this);
	}

	@Override
	// 實現事件處理方法
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Toast.makeText(MainActivity.this, "直接使用Activity作爲監聽器", 1).show();
	}
}



    4.匿名內部類作爲事件監聽器類   

    匿名內部類作爲事件監聽器類的優勢:

    大部分時候,事件處理器都沒有什麼複用價值(可複用代碼通常都被抽象成了業務邏輯方法),因此大部分事件監聽器只是臨時使用一次,所以使用匿名內部類形式的事件監聽器更合適。 


    匿名內部類作爲事件監聽器類的劣勢:

    語法不宜掌握。

示例:

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="匿名內部類作爲事件監聽器類" />

</LinearLayout>


MainActivity.java

package com.example.nimingneibulei;

public class MainActivity extends Activity {
	private Button bn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		bn = (Button) findViewById(R.id.bn);
		// 使用匿名內部類作爲事件監聽器
		bn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 事件監聽器的響應
				Toast.makeText(MainActivity.this, "匿名內部類作爲事件監聽器", 1).show();
			}
		});
	}
}



    5.直接綁定到標籤 

    對於很多Android界面組件標籤而言,它們都支持OnClick屬性,該屬性值就是一個形如xxx(View source)的方法的方法名。


示例:

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="clickHandler"
        android:text="直接綁定到標籤onClick" />

</LinearLayout>

    
MainActivity.java

package com.example.onclick;

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	// 定義一個事件處理方法
	// 其中source參數代表事件源
	public void clickHandler(View source) {
		Toast.makeText(MainActivity.this, "直接綁定到標籤onClick", 1).show();
	}
}


    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章