美文网首页
Android 事件拦截

Android 事件拦截

作者: 我要离开浪浪山 | 来源:发表于2023-05-04 22:52 被阅读0次

    1、事件的三种状态

    1、分发:dispatchTouchEvent;
    2、拦截:onInterceptTouchEvent;
    3、处理:onTouchEvent;

    结论:
    1、ViewGroup只有dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent;
    1、View只有dispatchTouchEvent和onTouchEvent;

    2、公共代码

    实例图.png
     btn_click.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e(TAG, "onClick");
                }
            });
    
    <?xml version="1.0" encoding="utf-8"?>
    <com.leo.clickevent.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:background="@color/teal_700"
        >
    
    
        <com.leo.clickevent.MyButton
            android:id="@+id/btn_click"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:background="@color/purple_200"
            android:text="子控件"
            />
    
    </com.leo.clickevent.MyFrameLayout>
    
    //自定义MyButton 
    public class MyButton extends Button {
        private static final String TAG = "lyy";
    
        public MyButton(Context context) {
            super(context);
        }
    
        public MyButton(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        // 只要事件来到改View,这个方法肯定执行
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            Log.e(TAG, "dispatchTouchEvent: 子View");
            return super.dispatchTouchEvent(event);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.e(TAG, "onTouchEvent: MotionEvent.ACTION_DOWN = " + MotionEvent.ACTION_DOWN);
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.e(TAG, "onTouchEvent: MotionEvent.ACTION_MOVE = " + MotionEvent.ACTION_MOVE);
                    break;
                case MotionEvent.ACTION_UP:
                    Log.e(TAG, "onTouchEvent: MotionEvent.ACTION_UP = " + MotionEvent.ACTION_UP);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.e(TAG, "onTouchEvent: MotionEvent.ACTION_CANCEL = " + MotionEvent.ACTION_CANCEL);
                    break;
            }
            return super.onTouchEvent(event);
        }
    
    }
    
    

    3、viewGroup拦截

    //自定义MyFrameLayout 
    public class MyFrameLayout extends FrameLayout {
        private static final String TAG = "lyy";
    
        public MyFrameLayout(@NonNull Context context) {
            super(context);
        }
    
        public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            Log.e(TAG, "dispatchTouchEvent: 父容器");
            return super.dispatchTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.e(TAG, "onTouchEvent: 父容器");
            return super.onTouchEvent(event);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.e(TAG, "onInterceptTouchEvent: 父容器");
    //        return super.onInterceptTouchEvent(ev);
            //返回为true,代表拦截
            return true;
        }
    }
    

    点击子View执行结果:

    dispatchTouchEvent: 父容器
    onInterceptTouchEvent: 父容器
    onTouchEvent: 父容器
    

    1、可以看到执行了ViewGroup的 dispatchTouchEvent、onInterceptTouchEvent、和onTouchEvent;

    4、viewGroup不拦截

    public class MyFrameLayout extends FrameLayout {
        private static final String TAG = "lyy";
    
        public MyFrameLayout(@NonNull Context context) {
            super(context);
        }
    
        public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            Log.e(TAG, "dispatchTouchEvent: 父容器");
            return super.dispatchTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.e(TAG, "onTouchEvent: 父容器");
            return super.onTouchEvent(event);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.e(TAG, "onInterceptTouchEvent: 父容器");
            //不拦截
            return super.onInterceptTouchEvent(ev);
        }
    }
    

    点击子View执行结果:

    dispatchTouchEvent: 父容器
    onInterceptTouchEvent: 父容器
    dispatchTouchEvent: 子View
    onTouchEvent: MotionEvent.ACTION_DOWN = 0
    dispatchTouchEvent: 父容器
    onInterceptTouchEvent: 父容器
    dispatchTouchEvent: 子View
    onTouchEvent: MotionEvent.ACTION_UP = 1
    

    1、可以看到先执行ViewGroup的dispatchTouchEvent、onInterceptTouchEvent然后执行子View的onTouchEvent: MotionEvent.ACTION_DOWN ;
    2、接着执行ViewGroup的dispatchTouchEvent、onInterceptTouchEvent然后执行子View的onTouchEvent: MotionEvent.ACTION_UP;

    相关文章

      网友评论

          本文标题:Android 事件拦截

          本文链接:https://www.haomeiwen.com/subject/edrfsdtx.html