基于回调的事件传播

前言

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值