Android View事件分发机制理解

androidxml布局概况
MainActiviity

public class MainActivity extends Activity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        init();
    }
    private void init() {
        tv.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    System.out.println("-----------DOWN-------");
                    break;
                case MotionEvent.ACTION_UP:
                    System.out.println("-----------UP-------");
                    break;
                default:
                    break;
                }
                //return false;
                return true;
            }
        });

    }
}

main.xml

<com.example.testevent.MyLinearLayout 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.testevent.MainActivity" >

    <com.example.testevent.MyTextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</com.example.testevent.MyLinearLayout>

其中MyLinearLayout继承LinearLayout

public class MyLinearLayout extends LinearLayout{

    @SuppressLint("NewApi")
    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 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
        int action = event.getAction();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("MyLinearLayout ---ACTION_DOWN ---");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("MyLinearLayout ---ACTION_UP ---");
            break;
        default:
            break;
        }
        System.out.println("MyLinearLayout ---onTouchEvent ---");       
        return true;
        //return super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        System.out.println("MyLinearLayout ---onInterceptTouchEvent ---");
        return super.onInterceptTouchEvent(ev);
        //return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        System.out.println("MyLinearLayout ---dispatchTouchEvent ---");
        return super.dispatchTouchEvent(ev);
        //return true;
    }

}

MyTextView继承TextView

public class MyTextView extends TextView {

    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
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        int action = event.getAction();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            System.out.println("MyTextView ---ACTION_DOWN ---");
            break;
        case MotionEvent.ACTION_UP:
            System.out.println("MyTextView ---ACTION_UP ---");
            break;
        default:
            break;
        }
        System.out.println("MyTextView ---onTouchEvent ---");
        return super.onTouchEvent(event);
       // return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        System.out.println("MyTextView ---dispatchTouchEvent ---");
        return super.dispatchTouchEvent(event);
        //return true;
    }
}

先看第一张图
这里写图片描述
通过图我们可以看到事件分发默认情况是由父控件捕捉向子控件传递,子控件不消费(但可以做自己的其他逻辑),最后再回传到父控件,父控件进行消费。
当子控件消费(onTouchEvent返回true)后,不再回传给父控件。这有点类似java的继承关系。如果父控件拦截(onInterceptTouchEvent返回true)之后,将不会传递给子控件。
再看第二张
这里写图片描述
通过图我们可以看到setOnTouchListener的优先级高于onTouchEvent。

最后,为了方便大家理解,我贴一下整理的输出内容,大家看图不明白,可以对着输出内容来理解

默认:
10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:07:55.076: I/System.out(2502): MyTextView ---dispatchTouchEvent ---
10-05 04:07:55.076: I/System.out(2502): MyTextView ---ACTION_DOWN ---
10-05 04:07:55.076: I/System.out(2502): MyTextView ---onTouchEvent ---
10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---ACTION_DOWN ---
10-05 04:07:55.076: I/System.out(2502): MyLinearLayout ---onTouchEvent ---


MyTextView-- onTouchEvent----return true===
10-05 04:14:15.616: I/System.out(2548): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:14:15.616: I/System.out(2548): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:14:15.616: I/System.out(2548): MyTextView ---dispatchTouchEvent ---
10-05 04:14:15.616: I/System.out(2548): MyTextView ---ACTION_DOWN ---
10-05 04:14:15.616: I/System.out(2548): MyTextView ---onTouchEvent ---
10-05 04:14:15.696: I/System.out(2548): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:14:15.696: I/System.out(2548): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:14:15.696: I/System.out(2548): MyTextView ---dispatchTouchEvent ---
10-05 04:14:15.696: I/System.out(2548): MyTextView ---ACTION_UP ---
10-05 04:14:15.696: I/System.out(2548): MyTextView ---onTouchEvent ---


MyTextView-- dispatchTouchEvent----return true===  //onTouchEvent&&dispatchTouchEvent----return true===
10-05 04:16:39.676: I/System.out(2591): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:16:39.676: I/System.out(2591): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:16:39.676: I/System.out(2591): MyTextView ---dispatchTouchEvent ---
10-05 04:16:39.746: I/System.out(2591): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:16:39.746: I/System.out(2591): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:16:39.746: I/System.out(2591): MyTextView ---dispatchTouchEvent ---


MyLinearLayout-- onTouchEvent----return true=== 
10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:22:09.476: I/System.out(2677): MyTextView ---dispatchTouchEvent ---
10-05 04:22:09.476: I/System.out(2677): MyTextView ---ACTION_DOWN ---
10-05 04:22:09.476: I/System.out(2677): MyTextView ---onTouchEvent ---
10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---ACTION_DOWN ---
10-05 04:22:09.476: I/System.out(2677): MyLinearLayout ---onTouchEvent ---
10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---ACTION_UP ---
10-05 04:22:09.546: I/System.out(2677): MyLinearLayout ---onTouchEvent ---



MyLinearLayout-- onInterceptTouchEvent----return true
10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---

MyLinearLayout-- dispatchTouchEvent----return true===
10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---

-------------------------------------------------------
setOnTouchListener--- return false=======

默认:
10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:48:19.746: I/System.out(3243): MyTextView ---dispatchTouchEvent ---
10-05 04:48:19.746: I/System.out(3243): -----------DOWN-------
10-05 04:48:19.746: I/System.out(3243): MyTextView ---ACTION_DOWN ---
10-05 04:48:19.746: I/System.out(3243): MyTextView ---onTouchEvent ---
10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---ACTION_DOWN ---
10-05 04:48:19.746: I/System.out(3243): MyLinearLayout ---onTouchEvent ---

MyTextView--dispatchTouchEvent----return true
10-05 05:00:27.706: I/System.out(3419): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:00:27.706: I/System.out(3419): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:00:27.706: I/System.out(3419): MyTextView ---dispatchTouchEvent ---
10-05 05:00:27.786: I/System.out(3419): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:00:27.786: I/System.out(3419): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:00:27.786: I/System.out(3419): MyTextView ---dispatchTouchEvent ---

MyTextView--onTouchEvent----return true
10-05 05:03:39.846: I/System.out(3462): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:03:39.846: I/System.out(3462): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:03:39.846: I/System.out(3462): MyTextView ---dispatchTouchEvent ---
10-05 05:03:39.846: I/System.out(3462): -----------DOWN-------
10-05 05:03:39.846: I/System.out(3462): MyTextView ---ACTION_DOWN ---
10-05 05:03:39.846: I/System.out(3462): MyTextView ---onTouchEvent ---
10-05 05:03:39.926: I/System.out(3462): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:03:39.936: I/System.out(3462): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:03:39.936: I/System.out(3462): MyTextView ---dispatchTouchEvent ---
10-05 05:03:39.936: I/System.out(3462): -----------UP-------
10-05 05:03:39.936: I/System.out(3462): MyTextView ---ACTION_UP ---
10-05 05:03:39.936: I/System.out(3462): MyTextView ---onTouchEvent ---

MyLinearLayout-- dispatchTouchEvent----return true===== MyTextView-- setOnTouchListener无效
10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---


MyLinearLayout-- onInterceptTouchEvent----return true===== MyTextView-- setOnTouchListener无效
10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---

MyLinearLayout-- onTouchEvent----return true===== 
10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:51:30.926: I/System.out(3374): MyTextView ---dispatchTouchEvent ---
10-05 04:51:30.926: I/System.out(3374): -----------DOWN-------
10-05 04:51:30.926: I/System.out(3374): MyTextView ---ACTION_DOWN ---
10-05 04:51:30.926: I/System.out(3374): MyTextView ---onTouchEvent ---
10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---ACTION_DOWN ---
10-05 04:51:30.926: I/System.out(3374): MyLinearLayout ---onTouchEvent ---
10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---ACTION_UP ---
10-05 04:51:31.006: I/System.out(3374): MyLinearLayout ---onTouchEvent ---

-------------------------------------------------------
setOnTouchListener--- return true=======

默认:
10-05 05:07:06.376: I/System.out(3506): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:07:06.376: I/System.out(3506): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:07:06.376: I/System.out(3506): MyTextView ---dispatchTouchEvent ---
10-05 05:07:06.376: I/System.out(3506): -----------DOWN-------
10-05 05:07:06.466: I/System.out(3506): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:07:06.466: I/System.out(3506): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:07:06.466: I/System.out(3506): MyTextView ---dispatchTouchEvent ---
10-05 05:07:06.466: I/System.out(3506): -----------UP-------

MyTextView--dispatchTouchEvent----return true
10-05 05:08:28.256: I/System.out(3549): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:08:28.256: I/System.out(3549): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:08:28.256: I/System.out(3549): MyTextView ---dispatchTouchEvent ---
10-05 05:08:28.356: I/System.out(3549): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:08:28.356: I/System.out(3549): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:08:28.356: I/System.out(3549): MyTextView ---dispatchTouchEvent ---

MyTextView--onTouchEvent----return true
10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): MyTextView ---dispatchTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): -----------DOWN-------
10-05 05:09:57.396: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:09:57.406: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:09:57.406: I/System.out(3592): MyTextView ---dispatchTouchEvent ---
10-05 05:09:57.426: I/System.out(3592): -----------UP-------

MyLinearLayout-- dispatchTouchEvent----return true==== MyTextView-- setOnTouchListener无效
10-05 04:31:52.536: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:31:52.636: I/System.out(2852): MyLinearLayout ---dispatchTouchEvent ---

MyLinearLayout-- onInterceptTouchEvent----return true===== MyTextView-- setOnTouchListener无效
10-05 04:28:40.086: I/System.out(2720): MyLinearLayout ---dispatchTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onInterceptTouchEvent ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---ACTION_DOWN ---
10-05 04:28:40.096: I/System.out(2720): MyLinearLayout ---onTouchEvent ---

MyLinearLayout-- onTouchEvent----return true
10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): MyTextView ---dispatchTouchEvent ---
10-05 05:09:57.316: I/System.out(3592): -----------DOWN-------
10-05 05:09:57.396: I/System.out(3592): MyLinearLayout ---dispatchTouchEvent ---
10-05 05:09:57.406: I/System.out(3592): MyLinearLayout ---onInterceptTouchEvent ---
10-05 05:09:57.406: I/System.out(3592): MyTextView ---dispatchTouchEvent ---
10-05 05:09:57.426: I/System.out(3592): -----------UP-------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值