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,那么事件将不会继续向外传播。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。