安卓高级4 事件分发
事件传递:由最上层依次传到最下层,不管最下层是否消费事件都需要返回告顶层,回传到顶层期间,如果第一次传递事件
案例:
场景1:点击屏幕,谁都不消费也不拦截.全部为默认super事件
场景2:点击屏幕,activity的dispatch为true
场景3:点击屏幕,activity的dispatch为false
由1-3得出结论:由于activity没有拦截事件(Intercept)所以返回ture或者false都是一样的,即不会调用activity的Ontouch方法也不会向下传递
所以当你需要传递事件的时候调用super方法,建议不要更换为true或者false场景4:点击屏幕,ViewGroup的dispatch为false
场景5:点击屏幕,ViewGroup的dispatch为true
由1,4,5得出结论:返回值为ture时由viewgroup的dispatch消费并且不调用其他方法,false会回调上个界面Activity的ontouch方法
如果需要传递向下使用super即可调用下个界面dispatch方法场景6:点击屏幕,ViewGroup的Intercept为ture
- 场景7:点击屏幕,ViewGroup的intercepter为false
- 场景8:点击屏幕移动,ViewGroup的intercepter为true 并且ontouch为false或者为super
场景9:点击屏幕移动,ViewGroup的intercepter为true 并且ontouch为true
由1,6,7得出结论:返回值为ture时由viewgroup的ontouch调用并且打断向下传播给view事件,并调用自身ontouch.此时如果ontouch返回值为super或者flase.其剩余事件如移动和松手都不会在向下传递给而是用activity分发事件然后直接调用ontouch
如果需要传递向下使用super或者false即可调用下个界面dispatch方法场景11:我们设置ViewGroup时候给其添加setOntouListenner代码如下
package qianfeng.com.toucheventdemo.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
/**
* Created by ${Mr.Zhao} on 2016/10/20.
*/
public class MyViewGroup extends RelativeLayout {
public MyViewGroup(Context context) {
super(context);
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Mr.Zhao", "ViewGroup-setOnTouchListener: " + event.getAction());
return true;
}
});
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Mr.Zhao", "ViewGroup-setOnTouchListener: " + event.getAction());
return true;
}
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("Mr.Zhao", "ViewGroup-dispatchTouchEvent: " + ev.getAction());
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("Mr.Zhao", "ViewGroup-onInterceptTouchEvent: " + ev.getAction());
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("Mr.Zhao", "ViewGroup-onTouchEvent: " + event.getAction());
return super.onTouchEvent(event);
}
}
只有在ViewGroup只有点击ViewGroup紫色区域不包括蓝色区域.如果点击蓝色区域不会调用setOntouListenner
- 情形设置监听返回值为ture
this.setOnTouchListener(new OnTouchListener() {
//aaaaa
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Mr.Zhao", "ViewGroup-setOnTouchListener: " + event.getAction());
return true;
}
});
结论:在viewgroup调用dispatch时候用super方法时候如果你设置了监听就调用setOntouch方法跳过拦截方法(Intercept)并且也不会直接运行本身的ontouch(Ovrride那个重写方法) 不是监听的匿名内部类的那个方法( //aaaaa)
- 情形设置监听返回值为false
this.setOnTouchListener(new OnTouchListener() {
//aaaaa
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("Mr.Zhao", "ViewGroup-setOnTouchListener: " + event.getAction());
return false;
}
});
结论:在viewgroup调用dispatch时候用super方法时候如果你设置了监听就调用setOntouch方法跳过拦截方法(Intercept) ,但是会执行本身的ontouch(Ovrride那个重修方法) 不是监听的匿名内部类方法( //aaaaa)