- Android 5從入門到精通
- 李波
- 2038字
- 2021-03-19 15:29:04
4.9 界面事件響應(yīng)
事件是Android平臺(tái)與用戶交互的手段。當(dāng)用戶對(duì)手機(jī)進(jìn)行操作時(shí),會(huì)產(chǎn)生各種各樣的輸入事件,Android框架捕獲到這些事件,進(jìn)而進(jìn)行處理。Android平臺(tái)提供了多種用于獲取用戶輸入事件的方式,考慮到用戶事件都是在特定的用戶界面中產(chǎn)生,因此Android選用使用特定View組件來獲取用戶輸入事件的方式,由View組件提供事件處理的方法。這就是為什么View類內(nèi)部帶有處理特定事件的監(jiān)聽器。
4.9.1 事件監(jiān)聽器
監(jiān)聽器用于對(duì)特定事件進(jìn)行監(jiān)聽,一旦監(jiān)聽到特定事件,則由監(jiān)聽器截獲該事件,并回調(diào)自身的特定方法對(duì)事件進(jìn)行處理。在本章之前的實(shí)例中,我們使用的事件處理方式都是監(jiān)聽器。根據(jù)用戶輸入方式的不同,View組件將截獲的事件分為6種,對(duì)應(yīng)以下6種事件監(jiān)聽器接口:
(1)OnClickListener接口:此接口處理的是單擊事件,例如,在View上進(jìn)行單擊動(dòng)作、在View獲得焦點(diǎn)的情況下單擊“確定”按鈕或者單擊軌跡球都會(huì)觸發(fā)該事件。當(dāng)單擊事件發(fā)生時(shí),OnClickListener接口會(huì)回調(diào)public void onClick(View v)方法對(duì)事件進(jìn)行處理。其中參數(shù)v指的是發(fā)生單擊事件的View組件。
(2)OnLongClickListener接口:此接口處理的是長按事件,當(dāng)長時(shí)間按住某個(gè)View組件時(shí)觸發(fā)該事件。其對(duì)應(yīng)的回調(diào)方法為public boolean onLongClick(View v),當(dāng)返回值true時(shí),表示已經(jīng)處理完此事件,若事件未處理完,則返回false,該事件還可以繼續(xù)被其他監(jiān)聽器捕獲并處理。
(3)OnFocusChangeListener接口:此接口用于處理View組件焦點(diǎn)改變事件。當(dāng)View組件失去或獲得焦點(diǎn)時(shí)會(huì)觸發(fā)該事件,其對(duì)應(yīng)的回調(diào)方法為public void onFocusChange(View v, Boolean hasFocus),其中參數(shù)v表示產(chǎn)生事件的事件源,hasFocus表示事件源的狀態(tài),即是否獲得焦點(diǎn)。
(4)OnKeyListener接口:此接口用于對(duì)手機(jī)鍵盤事件進(jìn)行監(jiān)聽,當(dāng)View獲得焦點(diǎn)并且鍵盤被敲擊時(shí)會(huì)觸發(fā)該事件。其對(duì)應(yīng)的回調(diào)方法為public boolean onKey(View v, int keyCode, KeyEvent event),其中參數(shù)keyCode為鍵盤碼,參數(shù)event便為鍵盤事件封裝類的對(duì)象。
(5)OnTouchListener接口:此接口是用來處理手機(jī)屏幕事件,當(dāng)在View的范圍內(nèi)觸摸、按下、抬起、滑動(dòng)等動(dòng)作時(shí)都會(huì)觸發(fā)該事件,并觸發(fā)該接口中的回調(diào)方法,其對(duì)應(yīng)的回調(diào)方法:public boolean onTouch(View v, MotionEvent event)對(duì)應(yīng)的參數(shù)同上。
(6)OnCreateContextMenuListener接口:此接口用于處理上下文菜單被創(chuàng)建的事件,其對(duì)應(yīng)的回調(diào)方法為public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info),其中參數(shù)menu為事件的上下文菜單,參數(shù)info是該對(duì)象中封裝了有關(guān)上下文菜單其他的信息。在4.5節(jié)的實(shí)例MenusDemo中,創(chuàng)建上下文菜單使用的是registerForContextMenu(View v)方法,其本質(zhì)是為View組件v注冊(cè)該接口,并實(shí)現(xiàn)了相應(yīng)的回調(diào)方法。
4.9.2 回調(diào)事件響應(yīng)
在Android框架中,除了可以使用監(jiān)聽器進(jìn)行事件處理之外,還可以通過回調(diào)機(jī)制進(jìn)行事件處理。Android SDK為View組件提供了五個(gè)默認(rèn)的回調(diào)方法,如果當(dāng)某個(gè)事件沒有被任意一個(gè)View處理,則會(huì)在Activity中調(diào)用響應(yīng)的回調(diào)方法,這些方法分別如下所示。
(1)public boolean onKeyDown(int keyCode, KeyEvent event)方法是接口KeyEvent.Callback中的抽象方法,當(dāng)鍵盤按鈕被按下時(shí)由系統(tǒng)調(diào)用。參數(shù)keyCode即鍵盤碼,系統(tǒng)根據(jù)鍵盤碼得知按下的是哪個(gè)按鈕。參數(shù)event為按鈕事件的對(duì)象,包含了觸發(fā)事件的詳細(xì)信息,例如事件的類型、狀態(tài)等。當(dāng)此方法的返回值為True時(shí),代表已完成處理此事件,返回false表示該事件還可以被其他監(jiān)聽器處理。
(2)public boolean onKeyUp(int keyCode, KeyEvent event)方法也是接口KeyEvent.Callback中的抽象方法,當(dāng)按鈕向上彈起時(shí)被調(diào)用,參數(shù)與onKeyDown()完全相同。
(3)public boolean onTouchEvent(MotionEvent event)方法在View中定義,當(dāng)用戶觸摸屏幕時(shí)被自動(dòng)調(diào)用。參數(shù)event為觸摸事件封裝類的對(duì)象,封裝了該事件的相關(guān)信息。當(dāng)用戶觸摸到屏幕,屏幕被按下時(shí),MotionEvent.getAction()的值為MotionEvent.ACTION_DOWN;當(dāng)用戶將觸控物體離開屏幕時(shí),MotionEvent.getAction()的值為MotionEvent.ACTION_UP;當(dāng)觸控物體在屏幕上滑動(dòng)時(shí),MotionEvent.getAction()的值為MotionEvent.ACTION_MOVE。onTouchEvent方法的返回值為true表示事件處理完成,返回false表示未完成。
(4)public boolean onTrackballEvent(MotionEvent event)方法的功能是處理手機(jī)中軌跡球的相關(guān)事件,可以在Activity中重寫,也可以在View中被重寫。參數(shù)event為手機(jī)軌跡球事件封裝類的對(duì)象。該方法的返回值為true表示事件處理完成,返回false表示未完成。
(5)protected void onFocusChanged(boolean gainFocus, int direction, Rect previously FocusedRect)方法只能在View中重寫,當(dāng)View組件焦點(diǎn)改變時(shí)被自動(dòng)調(diào)用,參數(shù)gainFocus表示觸發(fā)該事件的View是否獲得了焦點(diǎn),獲得焦點(diǎn)為true,參數(shù)direction表示焦點(diǎn)移動(dòng)的方向,參數(shù)previouslyFocusedRect是在觸發(fā)事件的View的坐標(biāo)系中前一個(gè)獲得焦點(diǎn)的矩形區(qū)域。
4.9.3 界面事件響應(yīng)實(shí)例
在之前的章節(jié)中,多次使用了監(jiān)聽器對(duì)事件進(jìn)行處理,讀者應(yīng)該已經(jīng)很熟悉了。本節(jié)通過一個(gè)實(shí)例來演示回調(diào)事件響應(yīng)的處理過程,該實(shí)例EventDemo運(yùn)行效果如圖4.50所示。

圖4.50 實(shí)例EventDemo運(yùn)行效果
其布局文件main.xml內(nèi)容如下:
<?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="回調(diào)事件處理演示" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="true" android:text="按鈕1"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="true" android:text="按鈕2"/> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusableInTouchMode="true" android:text="按鈕3"/> </LinearLayout> </LinearLayout>
當(dāng)用戶在屏幕上做移動(dòng)觸摸、單擊按鈕等操作時(shí),主Activity EventDemo會(huì)捕獲相應(yīng)事件并進(jìn)行處理,在LogCat中打印相關(guān)內(nèi)容,運(yùn)行效果如圖4.51所示。

圖4.51 Activity EventDemo捕獲事件
EventDemo.java代碼如下:
package introduction.android.eventDemo; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnFocusChangeListener; import android.widget.Button; import android.widget.Toast; public class EventDemo extends Activity implements OnFocusChangeListener { Button[] buttons=new Button[3]; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); buttons[0]=(Button)findViewById(R.id.button1); buttons[1]=(Button)findViewById(R.id.button2); buttons[2]=(Button)findViewById(R.id.button3); for(Button button :buttons){ button.setOnFocusChangeListener(this); } } //按鈕按下觸發(fā)的事件 public boolean onKeyDown(int keyCode,KeyEvent event) { switch(keyCode) { case KeyEvent.KEYCODE_DPAD_UP: DisplayInformation("按下上方向鍵,KEYCODE_DPAD_UP"); break; case KeyEvent.KEYCODE_DPAD_DOWN: DisplayInformation("按下下方向鍵,KEYCODE_DPAD_UP"); break; } return false; } //按鈕彈起觸發(fā)的事件 public boolean onKeyUp(int keyCode,KeyEvent event) { switch(keyCode) { case KeyEvent.KEYCODE_DPAD_UP: DisplayInformation("松開上方向鍵,KEYCODE_DPAD_UP"); break; case KeyEvent.KEYCODE_DPAD_DOWN: DisplayInformation("松開下方向鍵,KEYCODE_DPAD_UP"); break; } return false; } //觸摸事件 public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: DisplayInformation("手指正在往屏幕上按下"); break; case MotionEvent.ACTION_MOVE: DisplayInformation("手指正在屏幕上移動(dòng)"); break; case MotionEvent.ACTION_UP: DisplayInformation("手指正在從屏幕上抬起"); break; } return false; } //焦點(diǎn)事件 @Override public void onFocusChange(View view, boolean arg1){ switch(view.getId()){ case R.id.button1: DisplayInformation("第一個(gè)按鈕獲得了焦點(diǎn)"); break; case R.id.button2: DisplayInformation("第二個(gè)按鈕獲得了焦點(diǎn)"); break; case R.id.button3: DisplayInformation("第三個(gè)按鈕獲得了焦點(diǎn)"); break; } } //顯示Toast public void DisplayInformation(String string) { //Toast.makeText(EventDemo.this,string,Toast.LENGTH_SHORT).show(); Log.i("enentDemo",string); } }
- 企業(yè)級(jí)Java EE架構(gòu)設(shè)計(jì)精深實(shí)踐
- Java入門很輕松(微課超值版)
- AIRAndroid應(yīng)用開發(fā)實(shí)戰(zhàn)
- Swift 3 New Features
- Apache Mahout Clustering Designs
- PySide 6/PyQt 6快速開發(fā)與實(shí)戰(zhàn)
- PHP+MySQL+Dreamweaver動(dòng)態(tài)網(wǎng)站開發(fā)從入門到精通(第3版)
- Advanced Express Web Application Development
- 好好學(xué)Java:從零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)
- Developing SSRS Reports for Dynamics AX
- 零基礎(chǔ)學(xué)C語言程序設(shè)計(jì)
- 軟件工程基礎(chǔ)與實(shí)訓(xùn)教程
- Get Your Hands Dirty on Clean Architecture
- Getting Started with Web Components
- Go Systems Programming