Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 通過Android View的兩種事件響應方法比較inheritance和composition

通過Android View的兩種事件響應方法比較inheritance和composition

編輯:關於Android編程

Android view有兩種主要的處理事件的方式,   在View的子類中覆蓋onXXX方法。因為這是在子類中通過覆蓋的方式來響應事件,我稱之為基於繼承(inheritance)的響應方式。 調用View.setXXXListener,參數會實現View.OnXXXListener接口。因為View對象和Listner組合起來完成工作,我稱之為基於組合(composition)的響應方式。 例如對於touch事件而言,View.dispatchTouchEvent接收到touch事件對象,然後:   調用通過View.setOnTouchListener注冊的listener。 調用可以被子類覆蓋的onTouchEvent方法。 舉個簡單例子,一個Activity中有一個edit框(EditText對象)。EditText是通過代碼添加的到Activity中的。我希望在點擊它時,自動把該框的底色設置為紅色。   如果采用第一種方式,其EditText的子類是:   復制代碼 public class TouchChangeBackgroundColorEditText extends EditText {       public MyEditText(Context context, AttributeSet attrs) {         super(context, attrs);     }       @Override     public boolean onTouchEvent(MotionEvent event) {         this.setBackgroundColor(Color.RED);         return super.onTouchEvent(event);     } } 復制代碼 然後我們在Activity中使用該EditText的子類。   如果采用第二種方法,則需要創建一個對touch事件的listener:   復制代碼 public class TouchChangeBackgroundColorListener implements View.OnTouchListener {       @Override     public boolean onTouch(View v, MotionEvent event) {         v.setBackgroundColor(Color.RED);         return false;     } } 復制代碼 然後在Activity中使用普通EditText,並對該EditText調用setOnTouchListener(new TouchChangeBackgroundColorListener)。   然後用戶又想對某些EditText使用Key event來改變背景顏色,那如果采用基於繼承的方式,用戶需要創建KeyChangeBackGroundColorEditText的子類,在其中覆蓋onKeyDown方法;如果采用組合的方式,則需要實現OnKeyListener並添加到EditText中。   現在問題來了,用戶希望某些EditText是不響應touch和key事件的,有些只響應一種,有些兩種都響應。那麼如果采用繼承的方式,那需要四種對象,一個基本都EditText和三種針對only touch,only key和both touch and key的子類。   但如果采用組合的方式,我們仍然只需要兩個listener,只需對不同的EditText添加不同的listener即可。   如果更復雜,我們還想針對trackball改變顏色,那如果采用繼承,則可能有3×3=9種類。但采用組合,只需要三種listener,然後EditText根據需要添加即可。   所以說,在可能有多種因素導致變化的時候,繼承可能導致對象種類(即類)爆炸式增長;而組合可以用不同的對象封裝不同的變化,減少類的個數。   但這裡減少的只是編碼中類的個數,而在運行時如果采用繼承,那對象的個數是EditText的個數;但如果采用組合,那每個EditText都對應著一個Listener,所以有更多的對象個數。所以說,組合一般較繼承產生更多的運行時對象,這需要更多的內存(對象存儲)和運算時間(對象間相互調用)。   現在假設app的界面上已經有一個EditText控件,我們又想在app中通過選項來控制該EditText的行為,例如我們有三個選項,分別對應touch,key和trackball事件發生時是否改變該EditText的背景顏色。那麼如果采用組合,可以先創建好三個listener,然後根據選擇添加listener到現有的的EditText中。但如果使用繼承,根本是無法動態改變其行為了。所以說,組合可以動態改變對象的行為,而繼承只能在靜態改變。   再回到前面繼承的onTouchEvent方法,在最後一行,我需要調用super.onTouchEvent。事實上,我開始實現時忘記調用這行了,結果點擊edit框時,可以改變顏色,但無法切出輸入法。在現實中覆蓋父類的方法時,有的父類方法是需要在子類中被調用的,但有的卻不需要。覆蓋的時候要詳細查看父類文檔和代碼。但如果采用組合的方式,我只需要關系listener自己的視線即可,並不需要調用view中跟touch處理相關的代碼。所以說,繼承是一種白盒復用,在覆蓋父類的方法時,需要關心父類方法的實現;但組合是黑盒測試,我只需要實現接口即可,而不需要關心該接口如何被調用。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved