安卓高级4 事件分发

这里写图片描述
这里写图片描述

事件传递:由最上层依次传到最下层,不管最下层是否消费事件都需要返回告顶层,回传到顶层期间,如果第一次传递事件

案例:

状态图

  1. 场景1:点击屏幕,谁都不消费也不拦截.全部为默认super事件
    这里写图片描述

  2. 场景2:点击屏幕,activity的dispatch为true
    这里写图片描述

  3. 场景3:点击屏幕,activity的dispatch为false
    这里写图片描述

    由1-3得出结论:由于activity没有拦截事件(Intercept)所以返回ture或者false都是一样的,即不会调用activity的Ontouch方法也不会向下传递
    所以当你需要传递事件的时候调用super方法,建议不要更换为true或者false

  4. 场景4:点击屏幕,ViewGroup的dispatch为false
    这里写图片描述

  5. 场景5:点击屏幕,ViewGroup的dispatch为true
    这里写图片描述

    由1,4,5得出结论:返回值为ture时由viewgroup的dispatch消费并且不调用其他方法,false会回调上个界面Activity的ontouch方法
    如果需要传递向下使用super即可调用下个界面dispatch方法

  6. 场景6:点击屏幕,ViewGroup的Intercept为ture
    这里写图片描述

  7. 场景7:点击屏幕,ViewGroup的intercepter为false
    这里写图片描述
  8. 场景8:点击屏幕移动,ViewGroup的intercepter为true 并且ontouch为false或者为super
    这里写图片描述
  9. 场景9:点击屏幕移动,ViewGroup的intercepter为true 并且ontouch为true
    这里写图片描述

    由1,6,7得出结论:返回值为ture时由viewgroup的ontouch调用并且打断向下传播给view事件,并调用自身ontouch.此时如果ontouch返回值为super或者flase.其剩余事件如移动和松手都不会在向下传递给而是用activity分发事件然后直接调用ontouch
    如果需要传递向下使用super或者false即可调用下个界面dispatch方法

  10. 场景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)

posted on 2016-10-21 14:51  木鱼哥  阅读(95)  评论(0编辑  收藏  举报

导航