- Android開發:從0到1 (清華開發者書庫)
- 趙志榮
- 1880字
- 2020-11-28 16:13:37
5.3 事件處理模型
在圖形用戶界面的開發中,有兩個非常重要的內容:一個是界面布局,另一個是控件的事件處理。在Android中,事件處理秉承了JavaSE圖形用戶界面的處理方式和風格。
Android在事件處理的過程中,主要涉及三個概念:
? 事件源:事件發生的場所,通常就是各個控件,例如按鈕Button、文本框EditText和活動等。
? 事件:用戶在界面上的操作的描述,可以封裝成為一個類的形式出現,例如鍵盤操作的事件類是KeyEvent,觸摸屏的移動事件類是MotionEvent。與JavaSE圖形界面不一樣的是并非所有的事件都被封裝成為一個類,例如Button單擊事件就沒有封裝成為一個類的形式。
? 事件處理者:接收事件對象并對其進行處理的對象,事件處理一般是一個實現某些特定接口類創建的對象。
事件源、事件和事件處理者之間是如何運作的?例如:圖5-3所示的LabelButton實例,當單擊OK按鈕時,將Label標簽內容修改為HelloWorld,那么這里的OK按鈕就是事件源,單擊就是事件,處理“將Label標簽修改為HelloWorld”的對象(或程序代碼)被稱為事件處理者。
一個類(或程序代碼)能夠成為事件處理者,要求有兩個前提:一是要求實現特定接口,LabelButton實例OK按鈕事件處理者要求實現android.view.View.OnClickListener接口;二是事件處理者必須在事件源上注冊。
提示 事件處理者由于實現XXXListener接口,因此也稱為事件監聽器。本書以后將事件處理者統一稱為事件監聽器。
具體的事件處理代碼有很多種模型,下面會一一介紹。
5.3.1 活動作為事件監聽器
在這種事件處理模型中,事件監聽器是當前活動(Activity),活動實現android.view. View.OnClickListener接口。
下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中的MainActivity. java代碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ ① @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通過id獲得OK按鈕對象 Button btnOK =(Button) findViewById(R.id.button); ② //注冊事件監聽器 btnOK.setOnClickListener(this); ③ } /* * 實現View.OnClickListener接口方法 */ @Override public void onClick(View view){ ④ TextView text =(TextView) findViewById(R.id.textView); ⑤ text.setText("HelloWorld"); } }
當前界面的MainActivity實現View.OnClickListener接口,見代碼第①行。代碼第④行的onClick(View view)方法是實現View.OnClickListener接口所要求的方法,參數view是View類型,事實上該參數就是事件源Button對象。
代碼第③行是通過Button的setOnClickListener(View.OnClickListener listener)方法注冊事件監聽器為this,即MainActivity。
代碼第②行和第⑤行是通過id獲得控件對象,這些id都是布局文件activity_main.xml中聲明的控件id屬性。
布局文件activity_main.xml代碼如下:
<?xml version="1.0" encoding="utf-8"?> <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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.a51work6.labelbutton.MainActivity"> <TextView android:id="@+id/textView" ① android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="59dp" android:text="Label" android:textSize="18sp"/> <Button android:id="@+id/button" ② android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView" android:layout_centerHorizontal="true" android:layout_marginTop="49dp" android:text="OK"/> </RelativeLayout>
在布局文件activity_main.xml中,代碼第①行是聲明TextView(標簽)控件id為textView,代碼第②行是聲明Button控件的id為button。
? 屬性android:id="@+id/Button01"是Button按鈕的id,通過id可以找到此按鈕對象。
? 屬性android:layout_width="wrap_content"是設置寬度。
? 屬性android:layout_height ="wrap_content"是設置高度。
其中,寬和高都可以是wrap_content(適合文本大小)值,也可以是fill_parent(根據屏幕大小占滿)值,或是match_parent(匹配父容器大小)值,還可以是具體數字,例如200px。數字的單位可以是以下幾類:
? px:像素屏幕上的點。
? dp:與密度無關的像素,是一種基于屏幕密度的抽象單位。在每英寸160點的顯示器上,1dp = 1px;在大于160點的顯示器上可能增大。
? dip:與dp相同。
? sp:與刻度無關的像素,是與dp類似,但是可以根據用戶的字體大小首選項進行縮放等。
5.3.2 內部類事件監聽器
在這種事件處理模型中,事件監聽器是活動(Activity)類中聲明的內部類,該內部類也要求實現android.view.View.OnClickListener接口。
下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中MainActivity. java代碼如下:
public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通過id獲得OK按鈕對象 Button btnOK =(Button) findViewById(R.id.button); ① //注冊事件監聽器 btnOK.setOnClickListener(new ButtonOKOnClickListener()); ② } class ButtonOKOnClickListener implements View.OnClickListener{ ③ /* * 實現View.OnClickListener接口方法 */ @Override public void onClick(View view){ TextView text =(TextView) findViewById(R.id.textView); ④ text.setText("HelloWorld"); } } }
代碼第③行是實現android.view.View.OnClickListener接口的內部類ButtonOKOn-ClickListener,因此代碼第②行注冊事件監聽器時候,需要實例化ButtonOKOnClickListener。
注意 任何實現android.view.View.OnClickListener的接口類,都可以成為Button事件監聽器,無論它是內部類還是外部類。但是需要注意:如果外部類實現接口時,外部類無法訪問活動(Activity)中的視圖,所以代碼第①行和第④行無法使用findViewById方法,findViewById方法是在Activity或View類中定義的。
5.3.3 匿名內部類事件監聽器
既然內部類很適合作為事件處理模型,那么內部類的一個特例匿名內部類是否也適合事件處理呢?事實上,在Android中事件處理時經常使用匿名內部類,包括官方的很多源代碼都采用匿名內部類的方式。
下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中的MainActivity. java代碼如下:
public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通過id獲得OK按鈕對象 Button btnOK =(Button) findViewById(R.id.button); //注冊事件監聽器 btnOK.setOnClickListener(new View.OnClickListener(){ ① /* * 實現View.OnClickListener接口方法 */ @Override public void onClick(View v){ TextView text =(TextView) findViewById(R.id.textView); text.setText("HelloWorld"); } }); ② } }
上述代碼第①行~第②行是注冊事件監聽,其中new View.OnClickListener(){…}是典型的Java匿名內部類的寫法。
提示 匿名內部類就是在使用接口(或者抽象類)的時候,直接給出這個接口(或者抽象類)實現。在Java中,接口(或者抽象類)是不能實例化的,實例化的是它們的實現類。匿名內部類的優點是:編譯之后代碼緊湊,可以在一定程度上減少字節碼文件長度,提高虛擬機的加載速度,從而提高運行速度。它的缺點是:代碼可讀性差。
縱觀三種事件處理模型,各有利弊,用戶可以根據自己的喜好來選擇,在實際的應用開發過程中,事件處理情況會更加復雜,同一個事件源上會有多個不同事件,因此有的時候不是單一的一種處理模型,而是多種模型的結合。
- Learning Real-time Processing with Spark Streaming
- Redis Applied Design Patterns
- 信息可視化的藝術:信息可視化在英國
- 薛定宇教授大講堂(卷Ⅳ):MATLAB最優化計算
- PHP+MySQL+Dreamweaver動態網站開發實例教程
- PLC編程及應用實戰
- 機器學習與R語言實戰
- 寫給程序員的Python教程
- C++從入門到精通(第6版)
- Java Web開發教程:基于Struts2+Hibernate+Spring
- Python機器學習
- Learning Google Apps Script
- CISSP in 21 Days(Second Edition)
- 嵌入式Linux與物聯網軟件開發:C語言內核深度解析
- 瘋狂Java講義精粹