• ontouch、dispatchtouchevent、interceptouchevent-相关事件


    这几天一直在研究onTouch的相关方法,今天我们就来看看onTouchEvent、dispatchTouchEvent、onIntercepTouchEvent这三个方法在控件之间的传递顺序

    public boolean dispatchTouchEvent(MotionEvent ev)      //用于事件的分发

    public boolean onInterceptTouchEvent(MotionEvent ev)    //  用于事件的拦截

    public boolean onTouchEvent(MotionEvent ev)     //处理事件

    先看如下代码

    1)xml文件

    <RelativeLayout 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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.mygestrue.MainActivity" >
    
        <com.example.mygestrue.MyLinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
    
            <com.example.mygestrue.MyLinearLayoutT
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >
    
                <com.example.mygestrue.MyTextView
                    android:id="@+id/tv1"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:background="#0000ff"
                    android:text="@string/hello_world" />
    
                <com.example.mygestrue.MyTextViewT
                    android:layout_marginTop="50dp"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:background="#ff0000"
                    android:text="@string/hello_world" />
            </com.example.mygestrue.MyLinearLayoutT>
        </com.example.mygestrue.MyLinearLayout>
    
    </RelativeLayout>

    2)上面用到的几个自定义的类

    MyLinearLayout

    package com.example.mygestrue;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.LinearLayout;
    
    public class MyLinearLayout extends LinearLayout {
    
        public MyLinearLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        public MyLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        public MyLinearLayout(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "myll1_ontouchevent");
        return super.onTouchEvent(event);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.e("123", "myll1_dispatchTouchevent");
        return super.dispatchTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.e("123", "myll1_oninterceptouchevent");
        return super.onInterceptTouchEvent(ev);
    }
    }

    MyLinearLayoutT

    package com.example.mygestrue;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.LinearLayout;
    
    public class MyLinearLayoutT extends LinearLayout {
    
        public MyLinearLayoutT(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        public MyLinearLayoutT(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        public MyLinearLayoutT(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "myll2_ontouchevent");
        return super.onTouchEvent(event);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.e("123", "myll2_dispatchTouchevent");
        return super.dispatchTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.e("123", "myll2_oninterceptouchevent");
        return super.onInterceptTouchEvent(ev);
    }
    }

    MyTextView

    package com.example.mygestrue;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.TextView;
    
    public class MyTextView extends TextView {
    
        public MyTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        public MyTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        public MyTextView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "mytv1_ontouchevent");
        return super.onTouchEvent(event);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "mytv1_dispatchtouchevent");
        return super.dispatchTouchEvent(event);
    }
    }

    MyTextViewT

    package com.example.mygestrue;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.TextView;
    
    public class MyTextViewT extends TextView {
    
        public MyTextViewT(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            // TODO Auto-generated constructor stub
        }
    
        public MyTextViewT(Context context, AttributeSet attrs) {
            super(context, attrs);
            // TODO Auto-generated constructor stub
        }
    
        public MyTextViewT(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "mytv2_ontouchevent");
        return super.onTouchEvent(event);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.e("123", "mytv2_dispatchtouchevent");
        return super.dispatchTouchEvent(event);
    }
    }

    MainActivity

    package com.example.mygestrue;
    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.MotionEvent;
    public class MainActivity extends ActionBarActivity {
    ;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            // TODO Auto-generated method stub
        Log.e("123", "main_dispatchtouchevent");
            return super.dispatchTouchEvent(ev);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
    
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
    
            return super.onOptionsItemSelected(item);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // TODO Auto-generated method stub
            Log.e("123", "main_ontouchevent");
            // return super.onTouchEvent(event);
            return super.onTouchEvent(event);
        };
    
    }

    1.当我们点击屏幕空白处的时候,打印的log

    03-26 13:59:16.879: E/123(6400): main_dispatchtouchevent
    03-26 13:59:16.879: E/123(6400): myll1_dispatchTouchevent
    03-26 13:59:16.879: E/123(6400): myll1_oninterceptouchevent
    03-26 13:59:16.879: E/123(6400): myll2_dispatchTouchevent
    03-26 13:59:16.879: E/123(6400): myll2_oninterceptouchevent
    03-26 13:59:16.880: E/123(6400): myll2_ontouchevent
    03-26 13:59:16.881: E/123(6400): myll1_ontouchevent
    03-26 13:59:16.882: E/123(6400): main_ontouchevent
    
    03-26 13:59:17.748: E/123(6400): main_dispatchtouchevent
    03-26 13:59:17.748: E/123(6400): myll1_dispatchTouchevent
    03-26 13:59:17.748: E/123(6400): myll1_oninterceptouchevent
    03-26 13:59:17.749: E/123(6400): myll2_dispatchTouchevent
    03-26 13:59:17.749: E/123(6400): myll2_oninterceptouchevent
    03-26 13:59:17.749: E/123(6400): myll2_ontouchevent
    03-26 13:59:17.749: E/123(6400): myll1_ontouchevent
    03-26 13:59:17.751: E/123(6400): main_ontouchevent

    得出的结论是

    首先是Activity_dispatchTouchEvent->xml最外层容器_dispatchTouchEvent->xml最外层容器_onIntercepTouchEvent->下一层_dispatchTouchEvent->下一层_onIntercepTouchEvent->最末层_onTouchEvent->上一层_onTouchEvent->最外层_onTouchEvent->Activity_onTouchEvent

    现在我们更改一下这些touch事件的返回值,如下

    activity:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    linear1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
       

    打印的log如下

    03-26 14:31:32.237: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.267: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.283: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.300: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.317: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.335: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.341: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.914: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.933: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.951: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.968: E/123(6794): main_dispatchtouchevent
    03-26 14:31:32.985: E/123(6794): main_dispatchtouchevent
    03-26 14:31:33.002: E/123(6794): main_dispatchtouchevent
    03-26 14:31:33.006: E/123(6794): main_dispatchtouchevent

    只有main_dispatchtouchevent执行了

    activity:
    
     dispatchTouchEvent:false
     onTouchEvent :true
    
    linear1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
       

    打印log

    03-26 14:35:45.660: E/123(7058): main_dispatchtouchevent
    03-26 14:35:45.688: E/123(7058): main_dispatchtouchevent
    03-26 14:35:45.706: E/123(7058): main_dispatchtouchevent
    03-26 14:35:45.723: E/123(7058): main_dispatchtouchevent
    03-26 14:35:45.740: E/123(7058): main_dispatchtouchevent
    03-26 14:35:45.748: E/123(7058): main_dispatchtouchevent

    还是仅仅执行了main_dispatchtouchevent

    activity:
    
     dispatchTouchEvent:false
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true

    打印log

    03-26 14:38:26.545: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.563: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.580: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.598: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.615: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.632: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.649: E/123(7223): main_dispatchtouchevent
    03-26 14:38:26.650: E/123(7223): main_dispatchtouchevent

    结果还是一样:执行的是main_dispatchtouchevent

    activity:
    
     dispatchTouchEvent:false
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:false
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true

    打印log

    03-26 14:41:04.697: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.722: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.739: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.757: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.774: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.792: E/123(7352): main_dispatchtouchevent
    03-26 14:41:04.796: E/123(7352): main_dispatchtouchevent

    结果仍然没有改变 main_dispatchtouchevent被执行

    activity:
    
     dispatchTouchEvent:false
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:false
     onTouchEvent :true
     onInterceptTouchEvent:false
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    03-26 14:45:23.294: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.318: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.336: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.353: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.370: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.387: E/123(7487): main_dispatchtouchevent
    03-26 14:45:23.390: E/123(7487): main_dispatchtouchevent

    好吧,忽然感觉,这个时候,仅仅让activity中的ontouch事件纯粹返回true或者false是没有意义的,这样事件好像根本就没办法往下传了

    activity:
    
     dispatchTouchEvent:super.dispatchTouchEvent(ev)
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    03-26 14:51:18.871: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.872: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.896: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.897: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.912: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.913: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.929: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.929: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.947: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.948: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.964: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.964: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.978: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.978: E/123(7744): myll1_dispatchTouchevent
    03-26 14:51:18.979: E/123(7744): main_dispatchtouchevent
    03-26 14:51:18.979: E/123(7744): myll1_dispatchTouchevent


    我们看到,这时候,ll1接收到了main_dispatchtouchevent传过来的事件,但是,它并没有继续往下传

    activity:
    
     dispatchTouchEvent:super.dispatchTouchEvent(ev)
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:false
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    linear2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:true
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    03-26 14:54:58.037: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.037: E/123(7869): myll1_dispatchTouchevent
    03-26 14:54:58.039: E/123(7869): main_ontouchevent
    03-26 14:54:58.056: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.056: E/123(7869): main_ontouchevent
    03-26 14:54:58.073: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.073: E/123(7869): main_ontouchevent
    03-26 14:54:58.090: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.090: E/123(7869): main_ontouchevent
    03-26 14:54:58.108: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.108: E/123(7869): main_ontouchevent
    03-26 14:54:58.122: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.122: E/123(7869): main_ontouchevent
    03-26 14:54:58.122: E/123(7869): main_dispatchtouchevent
    03-26 14:54:58.123: E/123(7869): main_ontouchevent

    我们看到ll1接收到了main_dispatchtouchevent的事件,但是,这时候,ll1的dispatchtouchevent的返回值为false,就是说,这个事件不往下分发,而ll1的interceptouchevent返回值又为true,也就是说,事件拦截,所以它的ontouch就不执行了,这样,就直接执行到了main_touchevent了

    activity:
    
     dispatchTouchEvent:super.dispatchTouchEvent(ev)
     onTouchEvent :false
    
    linear1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
     onInterceptTouchEvent:false
    
    linear2:
    
     dispatchTouchEvent:false
     onTouchEvent :true
     onInterceptTouchEvent:false
    
    tv1:
    
     dispatchTouchEvent:true
     onTouchEvent :true
    
    tv2:
    
     dispatchTouchEvent:true
     onTouchEvent :true
  • 相关阅读:
    函数和常用模块【day04】:函数式编程(六)
    函数和常用模块【day04】:递归(五)
    函数和常用模块【day04】:函数参数及调用(二)
    函数和常用模块【day04】:函数介绍(一)
    第一模块:python基础语法
    Python基础【day03】:集合进阶(四)
    Python基础【day03】:字典进阶(二)
    Python基础【day02】:数据运算(二)
    Python基础【day01】:表达式if ...else语句(三)
    Python基础【day01】:Hello World程序(二)
  • 原文地址:https://www.cnblogs.com/zhangshuli-1989/p/zhangshuli_touch_150327095.html
Copyright © 2020-2023  润新知