1. 程式人生 > >Android程式設計之Listener偵聽的N種寫法及實現原理

Android程式設計之Listener偵聽的N種寫法及實現原理

寫下這個題目時突然想起魯迅筆下的孔乙已,茴香豆的幾種寫法,頗有些咬文嚼字的味道。雖然從事手機程式設計多年,但一直使用的是C和C++程式設計,由於安卓早期只支援JAVA開發,所以對於時下如火如荼的安卓系統,我一直觀之而未入之。現在由於工作需要開始研究安卓程式設計,由於以前主要使用C語言,乍遇JAVA,在思考方式上,寫法上,程式設計規範上所遇問題頗多。單單一個Listener方法,在是否使用匿名類匿名物件時,就是各種不同的寫法。OnClickListener和其他Listener方法一樣,都是View類的抽象介面,過載後就能使用,定義如下:
// 編譯自View.java (版本 1.5:49.0,無超級位)
public abstract static interface android.view.View$OnClickListener {
 
  // 方法描述符 #4 (Landroid/view/View;)V
  public abstract void onClick(android.view.View arg0);

  內部類:
    [內部類資訊: #1 android/view/View$OnClickListener, 外部類資訊: #7 android/view/View
     內部名: #9 OnClickListener, 訪問標誌:1545 public abstract static]
}
這是一個抽象介面的定義,在使用上可以像類一樣派生。抽象介面interface)和抽象類(class)是和C,C++不一樣的,但在JAVA中兩者比較相似,但卻又是不同的,有關這方面的概率可以從JAVA程式設計中瞭解到,C++程式設計師也許會對這兩者感覺不知所措,不知道該為某些實現建立抽象介面還是抽象類。這可能需要一定的程式碼實戰經驗才能更好的把握。
Listener在使用上有多種寫法,瞭解這些,對編寫程式好處比較有限,但對閱讀程式碼卻又是有用的。大約也可以像孔乙已一樣拿來炫耀吧,但我認為,這對初涉安卓程式設計的其他程式設計師來深入瞭解JAVA或者安卓程式設計,具有很重要的意義。本例使用了六種方法,由於JAVA語法的靈活性,很可能換種思考,一種新的方法就誕生了,所以本文僅做了解,不要讓他成為你的靈魂鎖鏈,導致限制了你在安卓領域做更深入更廣泛的探索和貢獻。當然如果你發現的新的寫法或者創造什麼新的寫法,也可以告訴我,大家一起學習。下面是程式程式碼:

使用eclipse建立安卓工程,假設工作名字使用button4,包使用com.mypack,在視窗中加入6個BUTTON.,使用預設命名,系統自動會命名為button1到button6,再加入一個editText,系統會自動命名為editText1.工程專案包名都可以隨意。

資源的main.xml檔案內容如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button3" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button4"
        android:onClick="Btn4OnClick" />

    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button5" />

    <Button
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button6" />


    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="click button">

        <requestFocus />

    </EditText>

</LinearLayout>

Button4Activity.java檔案內容為:
package com.mypack;

import com.mypack.R;
import android.app.Activity;
import android.os.Bundle;
import android.util.*;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.mypack.callOut;

public class Button4Activity extends Activity implements OnClickListener {
	/** Called when the activity is first created. */
	private Button m_button1, m_button2, m_button3, m_button4, m_button5,
	m_button6;
	public EditText ET;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		m_button1 = (Button) findViewById(R.id.button1);
		m_button2 = (Button) findViewById(R.id.button2);
		m_button3 = (Button) findViewById(R.id.button3);
		m_button4 = (Button) findViewById(R.id.button4);
		m_button5 = (Button) findViewById(R.id.button5);
		m_button6 = (Button) findViewById(R.id.button6);
		ET = (EditText) findViewById(R.id.editText1);
		/*
		 * 方法1,其中的this相當於new OnClickListener()物件, 即class test 中的一個物件,
		 * 而如果要用這種方式的話,public void onClick 方法必須寫在該test類中, 且在開頭使用implements
		 * OnClickListener, 即this物件可以直接呼叫該方法
		 */
		m_button1.setOnClickListener(this);
		//方法2,使用物件clickListener
		m_button2.setOnClickListener(clickListener);
		//方法3,使用匿名物件建立監聽,同方法論,可以看作另一種寫法
		m_button3.setOnClickListener(new Button.OnClickListener() {
			@Override
			public void onClick(View v) {
				String strTmp = "點選Button03";
				ET.setText(strTmp);
			}
		});
		//方法4,使用XML檔案建立時繫結方法Btn4OnClick
		//方法5,自己設計個監聽類,監聽的方法引用OnClickListener介面中的方法,建立的是匿名物件
		m_button5.setOnClickListener(new clickListener2());
		//方法6, 外部類實現事件監聽器介面,很少用   ,詳看檔案callout.java
		m_button6.setOnClickListener(new callOut(this));
	}

	@Override
	public void onClick(View v) {
		Log.i("log", "click");
		String strTmp = "點選Button01";
		ET.setText(strTmp);
	}
	public OnClickListener clickListener = new OnClickListener() {

		public void onClick(View v) {
			Log.i("log", "click");
			String strTmp = "點選Button02";
			ET.setText(strTmp);
		}
	};

	public class clickListener2 implements View.OnClickListener {

		public void onClick(View v) {
			Log.i("log", "click");
			String strTmp = "點選Button05";
			ET.setText(strTmp);
		}
	};

	public void Btn4OnClick(View view) {
		String strTmp = "點選Button04";
		ET.setText(strTmp);
	}
}
檔案中最後一個按鈕使用了類callOut,CALLOUT.java程式碼如下:
package com.mypack;

import android.app.Activity;  
import android.view.View;
import android.view.View.OnClickListener;
import com.mypack.Button4Activity;

public class callOut implements OnClickListener {
	private Button4Activity act;  
    public callOut(Activity activity)  
    {  
        act = (Button4Activity)activity;  
    }  
    @Override  
    public void onClick(View v)   
    {  
    	String strTmp = "點選Button06";  
    	act.ET.setText(strTmp);  
    }  

}

文章此致完,參考資料:

http://blog.csdn.net/wyw1213/article/details/6282277