zoukankan      html  css  js  c++  java
  • 安卓高级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)

  • 相关阅读:
    C++使用静态类成员时出现的一个问题
    C++中的const_cast
    【位运算与嵌入式编程】
    电压取反电路
    bzoj4769
    初赛
    noip2011day2
    uva1252
    codeforces 703d
    poj[1734]
  • 原文地址:https://www.cnblogs.com/muyuge/p/6152140.html
Copyright © 2011-2022 走看看