您的位置:首页 > 移动开发 > Android开发

Android编程学习笔记 之 基于回调的事件传播

2016-03-22 21:38 441 查看
Android的事件处理机制分为:

①监听 ②回调。

回调机制,就是用组件自身来处理自身的事件,而不是像监听机制一样使用事件监听器。

简单的说,就是写一个类,继承View类或者View类的子类(如Button等),然后重写父类中的某些方法。

下面是一个简单的自定义的继承自Button的类,重写了onTouchEvent方法

public class MyButton extends Button {
public MyButton(Context context, AttributeSet set){
super(context, set);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
System.out.println("测试");
return true;//事件的扩散,之后再进行解释
}
}

那么,如果我们想要使用这个自定义的Button,就只需要在XML布局中

<包名.MyButton		android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="单击我">

这样,在主Activity中,不用添加事件监听器,不用findViewById,即可实现点击后在控制台输出"测试"字样,极大的减少了Activity中的代码量。

还有一个问题,重写了onTouchEvent的返回值是什么意思呢?

那就是事件的扩散,比如

一个公司的前台业务员(事件监听器)接到一个尊贵的客人(事件Event),那么这个业务员就是负责端茶递水(处理事件),但是客人(事件Event)有大生意要谈,小小的业务员肯定做不了主,那么他就要向上级报告(return false),"臣妾做不到啊",这时,部门的经理(重写的onTouchEvent)就出面解决问题, 如果还是解决不了,那么再向上级报告(return false),这样一直往上级报告,直到中间某一层解决了客人的需求(return
true)
,那么就不用再向上级报告了。

根据书籍《疯狂Android讲义 第二版》中介绍:

当该组件上发生某个按键被按下的事件时,Android系统最先触发的应该是该按键上绑定的事件监听器,接着才触发该组件提供的事件回调方法,然后还会传播到该组件所在的Activity。

也就是说,事件扩散的优先级应该是:事件监听器(listener)→事件回调方法(MyButton)→Activity的回调方法(Activity)

那么问题来了,如果一直return false,即在Activity的回调方法中return false会怎么样呢?

希望有了解的人能够解答我的疑惑

以下是简单的Demo,点击按钮后在控制台依次输出Listener,Button,Activity

//Activity类

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button but = (Button) findViewById(R.id.myButton);
but.setOnTouchListener(new View.OnTouchListener() {//设置事件监听器
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
System.out.println("Listener");
return false;//事件扩散出去
}
});
}

@Override
public boolean onTouchEvent(MotionEvent event) {//Activity类的事件处理方法
super.onTouchEvent(event);
System.out.println("Activity");
return false;//事件扩散出去
}
}


//自定义的Button类

public class MyButton extends Button {
public MyButton(Context context, AttributeSet set){
super(context, set);
}

@Override
public boolean onTouchEvent(MotionEvent event) {//重写Button类中的事件处理方法
super.onTouchEvent(event);
System.out.println("MyButton");
return false;//事件扩散出去
}
}
<!--主Activity的XML布局文件-->

<包名.MyButton
android:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我"/>


参考文献:《疯狂Android讲义 第二版》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: