事件,我們并不陌生!
所有的基于UI的應用程式,事件都變得不可或缺!試想一下,如果我們做的程式單擊按鈕和其它控件都沒有反應,那麼就如同一個人在這個世界上聽不到聲音一樣!
Android為我們提供了兩種方式的事件處理:(1)基于監聽器的事件處理;(2)基于回調的事件處理。
對于基于監聽器的事件處理而言,主要就是為Android界面元件綁定特定的事件監聽器;對于基于回調的事件處理而言,主要做法是重寫Android元件特定的回調函數,Android大部分界面元件都提供了事件響應的回調函數,我們隻要重寫它們就行。
本章我們着重講一下基于監聽器的事件處理,基于回調的事件處理放在下一章講解。
相比于基于回調的事件處理,這是更具“面向對象”性質的事件處理方式。在監聽器模型中,主要涉及三類對象:
(1)事件源Event Source:産生事件的來源,通常是各種元件,如按鈕,視窗等。
(2)事件Event:事件封裝了界面元件上發生的特定事件的具體資訊,如果監聽器需要擷取界面元件上所發生事件的相關資訊,一般通過事件Event對象來傳遞。
(3)事件監聽器Event Listener:負責監聽事件源發生的事件,并對不同的事件做相應的處理。
一、第一種:内部類作為監聽器
将事件監聽器類定義成目前類的内部類。
a)使用内部類可以在目前類中複用監聽器類,因為監聽器類是外部類的内部類。
b)可以自由通路外部類的所有界面元件,這也是内部類的兩個優勢。
我們前面的例子全部采用的該種方式!
我們可以一起回顧一下:http://blog.csdn.net/jianghuiquan/article/details/8252430
1、activity_main.xml界面檔案
<RelativeLayout 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"
tools:context=".MainActivity" >
<EditText
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="34dp"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/passWord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/userName"
android:layout_marginTop="18dp"
android:ems="10"
android:inputType="textPassword" />
//定義了一個ID為login的按鈕
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/userName"
android:layout_below="@+id/passWord"
android:layout_marginTop="36dp"
android:text="登入" />
</RelativeLayout>
2、MainActivity.java程式檔案
package com.genwoxue.edittextbutton;
import android.os.Bundle;
import android.app.Activity;
import android.widget.EditText;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText tvUserName=null;
private EditText tvPassword=null;
private Button btnLogin=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvUserName=(EditText)super.findViewById(R.id.userName);
tvPassword=(EditText)super.findViewById(R.id.passWord);
btnLogin=(Button)super.findViewById(R.id.login);
//為按鈕注冊監聽事件
btnLogin.setOnClickListener(new LoginOnClickListener());
}
//事件監聽器
private class LoginOnClickListener implements OnClickListener{
public void onClick(View v){
String username=tvUserName.getText().toString();
String password=tvPassword.getText().toString();
String info="使用者名:"+username+"☆☆☆密碼:"+password;
Toast.makeText(getApplicationContext(), info,Toast.LENGTH_SHORT).show();
}
}
}

上面的理論也許聽起來讓你頭大,尤其java這一套事件監聽模型,讓很多盡管可能是其它語言程式設計高手也感覺甚不适應,但如果分析上面代碼,則發現實際也是非常簡單的。
我們這個案例中:單擊按鈕,顯示使用者名和密碼!
事件:單擊事件;
(1)注冊監聽事件:btnLogin.setOnClickListener(new LoginOnClickListener());
(2)事件監聽器:private class LoginOnClickListener implements OnClickListener
定義LoginOnClickListener類,從OnClickListener接口實作。
就這麼簡單!
二、第二種:匿名内部類作為事件監聽器類
如果事件監聽器隻是臨時使用一次,建議使用匿名内部類形式的事件監聽器更合适。
我們仍然以上述例子為例,加以改造,學習一下如何使用“匿名内部類作為事件監聽器類”。
1、界面部分不變!
activity_main.xml界面檔案
<RelativeLayout 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"
tools:context=".MainActivity" >
<EditText
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="34dp"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/passWord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/userName"
android:layout_marginTop="18dp"
android:ems="10"
android:inputType="textPassword" />
//定義了一個ID為login的按鈕
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/userName"
android:layout_below="@+id/passWord"
android:layout_marginTop="36dp"
android:text="登入" />
</RelativeLayout>
2、源程式加以改造!
MainActivity.java程式檔案
package com.genwoxue.anonymousinside;
import android.os.Bundle;
import android.app.Activity;
import android.widget.EditText;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText tvUserName=null;
private EditText tvPassword=null;
private Button btnLogin=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvUserName=(EditText)super.findViewById(R.id.userName);
tvPassword=(EditText)super.findViewById(R.id.passWord);
btnLogin=(Button)super.findViewById(R.id.login);
btnLogin.setOnClickListener(new OnClickListener(){
public void onClick(View v){
String username=tvUserName.getText().toString();
String password=tvPassword.getText().toString();
String info="使用者名:"+username+"☆☆☆密碼:"+password;
Toast.makeText(getApplicationContext(), info,Toast.LENGTH_SHORT).show();
}
});
}
}
三、對比
我們對比一下這兩種寫法:
1、第①種
(1)注冊:btnLogin.setOnClickListener(new LoginOnClickListener());
(2)内部類:
private class LoginOnClickListener implements OnClickListener{
public void onClick(View v){
String username=tvUserName.getText().toString();
String password=tvPassword.getText().toString();
String info="使用者名:"+username+"☆☆☆密碼:"+password;
Toast.makeText(getApplicationContext(), info,Toast.LENGTH_SHORT).show();
}
}
2、第②種
實際上是把①種合二為一了,使用匿名内部類直接完成了。
btnLogin.setOnClickListener(new OnClickListener(){
public void onClick(View v){
String username=tvUserName.getText().toString();
String password=tvPassword.getText().toString();
String info="使用者名:"+username+"☆☆☆密碼:"+password;
Toast.makeText(getApplicationContext(), info,Toast.LENGTH_SHORT).show();
}
});