Andorid事件处理 基于回调的事件处理

来源:互联网 发布:java intent bundle 编辑:程序博客网 时间:2024/04/30 09:12

Andorid事件处理

在Andorid中已经很完善的包装了关于事件处理的方式,主要有两套机制:

  • 基于监听的事件处理
  • 基于回调的事件处理
    对于Android基于回调的时间处理来说: 主要做法重写Andorid组件特定的回调方法。Android中已经为大部分界面控件提供了回调方法,调用就好。

对于Android监听的事件处理而言,就是我们经常遇到的组件绑定的事件监听器。
这篇文章主要写基于回调的事件处理,监听机制在我的上一篇文章中已经介绍

我自己的看法:回调机制取消了事件监听器,事件源和事件监听器合并。当用户在GUI组件上激发某个事件时,组件自己特定的方法(我们写的)将会负责处理该事件。我们需要做的就是为组件提供或者重写特定的处理方法。(注意,Java是一门静态的语言,没办法动态的添加方法,在这种情况下我们只能重写事件处理方法)

Android为所有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(int keyCode, KeyEvent event)     boolean onTrackballEvent(MotionEvent, KeyEvent event)

下面举一个简单的例子来实验下回调机制
首先是一个简单的xml布局文件,设置一个Button

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <com.example.administrator.itentlearn.MyButton        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="New Button"        android:id="@+id/button1"        android:layout_gravity="center_horizontal" /></LinearLayout>

大家注意看当中的

<com.example.administrator.itentlearn.MyButton

这是一个自定义View
接下来我们来看看这个MyButton的实现方法

import android.app.Activity;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.widget.Button;import android.widget.Toast;/** * Created by Administrator on 2017/3/9 0009. */public class MyButton extends Button{    public MyButton(Context context, AttributeSet set){        super(context, set);    }    /**     * 这里重写onKeyDown方法,该按钮会自己处理相应的事件     * @param keyCode     * @param event     * @return     */    @Override    public boolean onKeyDown(int keyCode, KeyEvent event){        super.onKeyDown(keyCode, event);        Log.v("Tag","first界面的绑定监听器");        //返回true,表明事件不会向外扩散        return true;    }}

这里利用MyButton继承Button类,实现接口onKeyDown,在GUI组件被被触发的时候回自动调用onKeyDown方法,不需要去绑定。其中onKeyDown方法的返回类型是true表明当前时间我已经在当前方法(onKeyDown)中处理完毕,不会向外传播,外部即使是绑定了其他的监听器也收不到消息。


基于回调机制下的事件传播
几乎所有的回调事件处理方法都有一个boolean类型的返回值。这个返回值和上文当中的一样用来标记当前事件是否已经处理完毕。

  • true :表明当前方法已经完全处理该事件,并且当前事件并不会向外传播
  • false:表明当前方法并未完全处理该事件,该事件会传播出去

对于事件传播的状态来说,组件上说发生的事件不仅激发该组件上的回调方法,也是出发组件所在Activity的回调方法。

下面的代码大家注意看
首先是一个xml布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <com.example.administrator.itentlearn.MySecondButton        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="New Button"        android:id="@+id/button_second1"        android:layout_gravity="center_horizontal" /></LinearLayout>

在对应的MySecondButton文件中实现了对应的回调处理方法

import android.content.Context;import android.inputmethodservice.Keyboard;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.widget.Button;/** * Created by Administrator on 2017/3/9 0009. */public class MySecondButton extends Button {    public MySecondButton(Context context, AttributeSet set){        super(context, set);    }    /**     * 重写onKeyDown方法,记住返回FALSE     * @param keyCode     * @param event     * @return     */    @Override    public boolean onKeyDown(int keyCode, KeyEvent event){        super.onKeyDown(keyCode, event);        Log.v("Log","second界面的回调事件处理,返回FALSE");//      返回FALSE表明该事件还未处理完,会向外扩散        return false;    }}

并且在main中野绑定了该组件对应的监听方法:

import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.widget.Button;/** * Created by Administrator on 2016/7/31 0031. */public class second extends AppCompatActivity {    private Button bt1;    @Override    public void onCreate (Bundle savedInstanceState){        super.onCreate(savedInstanceState);        setContentView(R.layout.second);        bt1 = (Button) findViewById(R.id.button_second1);        bt1.setOnKeyListener(new View.OnKeyListener() {            @Override            public boolean onKey(View view, int i, KeyEvent keyEvent) {//              只要处理按下的事件                if (keyEvent.getAction() == KeyEvent.ACTION_DOWN){                    Log.v("Log","界面二的绑定监听事件处理,返回FALSE");                }//              返回FALSE表明事件会向外传播                return false;            }        });    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event){        super.onKeyDown(keyCode, event);        Log.v("Log","onKeyDown事件处理,返回FALSE");        return false;    }}

最终实现完成后的样子(markdown不会贴图用的数据流)

03-09 10:31:32.588 7587-7587/com.example.administrator.itentlearn V/Log: 界面二的绑定监听事件处理,返回FALSE03-09 10:31:32.588 7587-7587/com.example.administrator.itentlearn V/Log: second界面的回调事件处理,返回FALSE03-09 10:31:32.588 7587-7587/com.example.administrator.itentlearn V/Log: onKeyDown事件处理,返回FALSE

RUA!!!
大家可以看到Android最先触发的是按键上绑定的事件监听器,接着才是该组件提供的事件回调方法,最后才是传播到组件所在Activity。

所以好吧,我推荐使用监听的方式来写事件处理。

回调机制的缺点:

  • 可能造成程序结构混乱,Activity主要的职责是完成界面的初始化工作,但又包含了事件处理器的方法,很乱。没有实现软件工程的精髓:高内聚,低耦合。
0 0
原创粉丝点击