前言
android为用户提供了两套强大的事件处理机制:
1:基于监听的事件处理
2:基于回调的事件处理
几乎所有基于回调的事件处理方法都有一个boolean类型的返回值,该返回值用于表示该处理方法是否能完全处理该事件
如果处理事件的回调方法返回true,表明该处理方法已经完全处理改事件,该事件不会传播出去。
如果处理事件的回调方法返回false,表明该处理方法并未完全处理该事件,该事件会传播出去。
对于基于回调的时间传播而言,某组件上所发生的事件不仅会激发该组件上的回调方法,也会触发该组件所在Activity的回调方法——只要事件能传播到该Activity。
下面的程序示范了Android系统中的事件传播,该程序重写了Button类的onKeyDown(int keyCode,KeyEvent event)方法,而且重写了该Button所在Activity的onKeyDown(int keyCode,KeyEvent event)方法,而且重写了该Button所在Activity的onKeyDown(int keyCode,KeyEvent event)方法———程序没有阻止事件传播,因此程序可以看到事件从Button传播到Activity的情形。
下面是从Button派生而出的MyButton子类代码
public class MyButton extends android.support.v7.widget.AppCompatButton {
public MyButton(Context context , AttributeSet set)
{
super(context , set);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
super.onKeyDown(keyCode , event);
Log.v("-MyButton-", "the onKeyDown in MyButton");
// 返回false,表明并未完全处理该事件,该事件依然向外扩散
return true;
}
}
上面的MyButton子类重写了onKeyDown(int keyCode,KeyEvent event)方法,当用户在该按钮上按下某个键时将会触发该方法。但是由于该方法返回了false,这意味着该事件还会继续向外传播。
看如下Activity类代码。
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bn = (Button) findViewById(R.id.bn);
Log.v("-Listener-", "the onKeyDown in Listener");
// 为bn绑定事件监听器
bn.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View source
, int keyCode, KeyEvent event) {
// 只处理按下键的事件
if (event.getAction() == KeyEvent.ACTION_DOWN) {
Log.v("-Listener-", "the onKeyDown in Listener");
}
// 返回false,表明该事件会向外传播
return false; // ①
}
});
}
// 重写onKeyDown方法,该方法可监听它所包含的所有组件的按键被按下事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
super.onKeyDown(keyCode , event);
Log.v("-Activity-" , "the onKeyDown in Activity");
//返回false,表明并未完全处理该事件,该事件依然向外扩散
return true;
}
}
从上面的程序可以看出,Activity中的onKeyDown(int keyCode,KeyEvent event)方法被重写,当在该Activity包含的所有组件上按下某个键时,该方法都可能被触发——只要该组件没有完全处理该事件。
不仅如此,上面的程序还采用监听模式来处理该按钮上的按键被按下事件。
运行程序,先把焦点移动到程序界面的按钮上,然后按下按键,将可在LogCat中看到输出
2019-02-27 19:34:46.993 2702-2702/com.example.myapplication V/-Listener-: the onKeyDown in Listener
2019-02-27 19:34:46.993 2702-2702/com.example.myapplication V/-MyButton-: the onKeyDown in MyButton
2019-02-27 19:34:46.993 2702-2702/com.example.myapplication V/-Activity-: the onKeyDown in Activity
从结果中可以看出,当该组件上发生某个按键被按下的事件时,Android系统最先触发的应该是该按键上绑定的事件监听器,然后才触发该组件提供的事件回调方法,最后还会传播到该组件所在的Activity——但如果我们让任何一个事件处理方法返回了true,那么该事件将不会继续向外传播