標籤:android應用
如果說事件監聽機制是一種委託式的事件處理,那麼回調機制則與之相反,對於基於回調的事件處理模型來說,事件來源和事件監聽器是統一的,或者說事件監聽器完全消失了,當使用者在GUI控制項上激發某個事件時,控制項自己特定的方法將會負責處理該事件。轉載請表明出處:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
一、View類的常見回調方法 為了使用回調機制來處理GUI控制項上所發生的事件,需要為該組件提供對應的事件處理方法,而Java又是一種靜態語言,我們無法為每個對象動態地添加方法,因此只能通過繼承GUI控制項類,並重寫該類的事件處理方法來實現。 Android平台中,每個View都有自己處理特定事件的回調方法,我們可以通過重寫View中的這些回調方法來實現相應的事件。
二、基於回調的事件處理開發方法
1.自訂控制項的一般步驟(1)定義自己組件的類名,並讓該類繼承View類或一個現有的View的子類;(2)重寫父類的一些方法,通常需要提供一個構造器,構造器是建立自訂控制項的基本方式。當Java代碼建立該控制項或根據XML布局檔案載入並構建介面時都將調用該構造器,根據業務需要重寫父類的部分方法。例如onDraw方法,用於實現介面顯示,其他方法還有onSizeChanged()、onKeyDown()、onKeyUp()等。(3)使用自訂的組件,既可通過Java代碼來建立,也可以通過XML布局檔案進行建立,需要注意的是在XML布局檔案中,該組件的標籤是完整的包名+類名,而不再僅僅是原來的類名。
2.源碼實戰
實現:自訂一個按鈕,重寫其觸摸的回調方法。
(1)MyButton.java:自訂群組件
package com.example.android_event2;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.widget.Button;import android.widget.Toast;public class MyButton extends Button{ //構造方法 public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } //回調方法 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); Toast.makeText(getContext(),"您按下了數字:"+keyCode,Toast.LENGTH_SHORT).show(); return true;//返回true,表明該事件不會向外擴散 }}
(2)layouyt/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <!--方法一:在XML布局檔案中建立組件--> <com.example.android_event2.MyButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="回調測試" /></LinearLayout>(3)MainActivity.java:主Activitypackage com.example.android_event2;import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //方法二:Java代碼中配置自訂群組件 }}效果示範:
源碼分析:在布局檔案中配置自訂的組件----> <完整的包名.類名 需要設定的相關屬性/>
三、事件處理的傳播
1. 基於回調方法事件處理的傳播 幾乎所有基於回調的事件處理方法都有一個boolean類型的返回值,該返回值用於標識該處理方法是否能完全處理該事件。 如果處理事件的回調方法返回true,表明該處理方法已完全處理該事件,該事件不會傳播出去; 如果處理事件的回調方法返回false,表明該處理方法並未完全處理該事件,該事件將會繼續向外傳播。 對於基於回調事件傳播而言,某組件上所發生的事情不僅激發該組件上的回調方法,也會觸發該組件所在Activity的回調方法(前提是事件能傳播到Activity)。
2.源碼實戰實現:自訂一個按鈕,重寫其觸摸的回調方法、為其註冊觸摸事件監聽器並重寫它所在Activity上的觸摸回調方法,觀察事件處理順序。
(1)MainActivity.java
package com.example.android_event2;import android.app.Activity;import android.os.Bundle;import android.view.KeyEvent;import android.view.View;import android.view.View.OnKeyListener;import android.widget.Button;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //採用監聽模式 Button myButton = (Button)findViewById(R.id.btn); myButton.setOnKeyListener(new OnKeyListener(){ public boolean onKey(View v, int keyCode, KeyEvent event) { System.out.println("組件所綁定的事件監聽器被觸發"); return false; } }); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); System.out.println("該組件所在的Activity的回調方法onKeyDown被調用"); return false;//返回true,表明該事件不會向外擴散 }}
(2)MyButton.java
package com.example.android_event2;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.widget.Button;public class MyButton extends Button{ //構造方法 public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } //回調方法 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); System.out.println("自訂群組件中的回調方法onKeyDown被調用"); return false;//返回true,表明該事件不會向外擴散 }}
(3)layout/main.xml
package com.example.android_event2;import android.content.Context;import android.util.AttributeSet;import android.view.KeyEvent;import android.widget.Button;public class MyButton extends Button{ //構造方法 public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } //回調方法 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { super.onKeyDown(keyCode, event); System.out.println("自訂群組件中的回調方法onKeyDown被調用"); return false;//返回true,表明該事件不會向外擴散 }}
效果示範:
源碼分析: 通過實驗結果可知,當隨意按下一個鍵後。 最先觸發的是該組件所綁定的事件監聽器,接著才觸發該組件提供的事件回調方法,最後才傳播到該組件所在的Activity。如果我們讓任何一個事件處理方法返回了true,那麼該事件將不會繼續向外傳播。
四、直接綁定到標籤 Android提供了一種直接在介面布局檔案中為指定標籤綁定事件處理方法的機制。對於很多Android介面控制項而言,它們都支援如onClick、onLongClick等屬性,這些屬性的屬性值是一個形如xxx(View source)方法的方法名。例如,在布局檔案中為按鈕添加單擊事件的處理方法如下:<Button android:layout_width=”wrap_content” android:layout_heigth=”wrap_content” android:text=”單擊我” android:onClick=”clickHandler”/>
1.源碼實戰
(1)MainActivity.java
package com.example.android_event3;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.EditText;public class MainActivity extends Activity { private EditText text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (EditText)findViewById(R.id.result); } //將clickHandler方法直接綁定到標籤 public void clickHandler(View source) { text.setText("中華人民共和國萬歲!"); }}
(2)layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="單擊我" android:onClick="clickHandler"/> <EditText android:id="@+id/result" android:inputType="none" android:layout_width="match_parent" android:layout_height="wrap_content"/></LinearLayout>
效果示範:
Android筆記二十四.Android基於回調的事件處理機制