Android的事件處理---監聽機制和回調機制-總結


 

Android有兩種方式的事件處理:

          1、基於回調的事件處理    2、基於監聽器的事件處理

一、先來大概說明一下監聽器的事件處理的實現原理

(學過AWT 、Swing的同學對監聽器基本有一點了解。)

 ===》》》  監聽事件是一種“面向對象”的事件處理  《《《===

涉及三類對象:

  • Event Source(事件源): 也就是按鈕,菜單,窗口等
  • Event(事件):就是操作的狀態,單擊、觸摸、長按、雙擊等
  • Event Listener(事件監聽器):對用戶的操作做出響應,也就是單擊按鈕了使他有反應

既然他們都是獨自的對象,處理方式也就比較寬泛。一個監聽器中可以有多個事件被監聽

       

public class MainActivity extends Activity {

    private Button button1, button2, button3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        button1.setOnClickListener(listener);
        button2.setOnClickListener(listener);
        button3.setOnClickListener(listener);
    }

    private OnClickListener listener = new OnClickListener() {

        @Override
        public void onClick(View view) {
            switch (view.getId()) {
            case R.id.button1:
                Toast.makeText(MainActivity.this,"點擊了button1", 1).show();
                break;
            case R.id.button2:
                Toast.makeText(MainActivity.this,"點擊了button2", 1).show();
                break;
            case R.id.button3:
                Toast.makeText(MainActivity.this,"點擊了button3", 1).show();
                break;
            }
        }
    };
}

      通過view.getId()來獲取不同的組件,switch來判斷不同組件的事件

當然,一個事件源也可以有多個不同的監聽器監聽不同的事件,菜單可以有單擊事件,也可以有長按事件。

      

有個有意思的比喻:說android的事件處理機制是一種委派式事件處理方式,普通UI組件將發生的事件交給監聽器去處理,自己不處理。好比如:發生火災了,交給消防局處理,發生打架了交給公安局處理,並且消防局和公安局又可以同時處理多個火災和打架事件。  這樣的委派式處理方式提高了程序的可維護性。挺好。

 

====》》》  實現監聽器的5種形式 《《《===

1、內部類形式,此時監聽器可以被復用,監聽器還可以自由訪問外部類中所有界面組件

2、外部類形式(這種方式少見),首先不利於提高程序內聚性,而且監聽器也不能自由訪問界面中組件。當然也有用到的時候,比如某個監聽器需要被多個GUI界面所共享的時候。

3、Activity本身作為監聽器(更少見),implements OnClickListener (特例)就可以實現

4、匿名內部類(使用廣泛),

   button.setOnClickListener(new OnClickListener(){

            @override

            Public void onClick(View v){

            }

      }

);

注意: new的監聽器可以放在方法的括號中,當多個按鈕需要實現這種監聽時可以拿出來,制定給某個變量,(上面介紹的一個監聽器中可以有多個事件被監聽的代碼就是這樣)

5、還可以直接綁定到標簽

比如Button的一個屬性 android:onClick=“clickHandler”

接下來實現一個clickHandler方法就可以了、注意要傳一個View參數,不然沒有反應 View形參代表被單擊的UI組件。

Public void clickHandler( View  source) {  }

 

 

二、 下面說一下基於回調的事件處理

  1、上面的監聽機制是一種委托式處理,那么回調機制則相反,回調機制則是發生某個事件時UI組件自己處理事件。

  (貌似基於回調的事件處理是用在自定義的UI組件中)

自定義某個組件然后繼承該GUI組件類,並重寫該類事件處理方法

   以View為例、先說一下常見的方法:

  • boolean  onKeyDown(int keyCode, KeyEvent event)  按下
  • boolean  onKeyLongPress(int keyCode, KeyEvent event) 長按
  • boolean  onKeyShortcut(int keyCode, KeyEvent event)  鍵盤快捷鍵事件觸發
  • boolean  onKeyUp(int keyCode ,KeyEvent event)  松開某個鍵
  • boolean  onTouchEvent(MotionEvent  event) 觸屏事件
  • boolean  onTrackballEvent(MotionEvent event)  軌跡球屏事件

 

在界面布局中使用自定義View時,要用全限定類名(包名.類名),

           有個簡單方法:將鼠標光標放在自定義類上面,將出現的框中內容直接復制就行

 

  2、基於回調事件的傳播

     所有基於回調的事件處理方法都有一個boolean類型的返回值,該返回值用於標識該處理方法能否完全處理該事件

  True : 表示該處理方法已完全處理該事件,事件不會傳播出去

  False: 沒有完全處理該事件,事件會傳播出去

 

既然要傳播,都傳向哪里呢,下面介紹

  有3個地方需要返回boolean類型,也就是事件是否完全處理

(1)   自定義組件重寫的回調方法return一個

      

 1 import android.content.Context;
 2 import android.util.AttributeSet;
 3 import android.util.Log;
 4 import android.view.KeyEvent;
 5 import android.widget.Button;
 6 
 7 public class MyButton extends Button
 8 {
 9     public MyButton(Context context , AttributeSet set)
10     {
11         super(context , set);
12     }
13     @Override
14     public boolean onKeyDown(int keyCode, KeyEvent event)
15     {
16         super.onKeyDown(keyCode , event);
17         Log.v("--MyButton--" , "the onKeyDown in MyButton");
18         // 返回false,表明並未完全處理該事件,該事件依然向外擴散
19         return false;
20     }
21 }

(2)   綁定監聽機制實現的事件處理方法中 return 一個

      

 1 @Override
 2     public void onCreate(Bundle savedInstanceState)
 3     {
 4         super.onCreate(savedInstanceState);
 5         setContentView(R.layout.main);
 6         Button bn = (Button) findViewById(R.id.bn);
 7         // 為bn綁定事件監聽器
 8         bn.setOnKeyListener(new OnKeyListener()
 9         {
10             @Override
11             public boolean onKey(View source
12                     , int keyCode, KeyEvent event)
13             {
14                 // 只處理按下鍵的事件
15                 if (event.getAction() == KeyEvent.ACTION_DOWN)
16                 {
17                     Log.v("-Listener-", "the onKeyDown in Listener");
18                 }
19                 // 返回false,表明該事件會向外傳播  
20                 return true; //
21             }
22         });
23     }

 

(3)   Activity中重寫回調方法,return一個

       

1 // 重寫onKeyDown方法,該方法可監聽它所包含的所有組件的按鍵被按下事件
2     @Override
3     public boolean onKeyDown(int keyCode, KeyEvent event)
4     {
5         super.onKeyDown(keyCode , event);
6         Log.v("-Activity-" , "the onKeyDown in Activity");
7         //返回false,表明並未完全處理該事件,該事件依然向外擴散
8         return false;
9     }

 

   下面說一下傳播的順序:

   傳播順序是:首先傳播到組件綁定的監聽器上,然后是自定義組件重寫的事件方法,最后傳播到組件所在Activity,當然,如果任何一個返回了true,那么事件將不會繼續向外傳播。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM