Android5.1 触摸屏事件分发机制和源码解析二 --(ViewGroup篇)

来源:互联网 发布:淘宝卡卡lee 编辑:程序博客网 时间:2024/06/03 21:50

一。案例分析

还是和上文一样,写一个非常简单的项目。

我们自定义了一个LinearLayout和Button控件。

由代码中,我们可以发现LinearLayout比Button多了一个onInterceptTouchEvent()方法。

MyLinearLayout.java

package com.example.viewanalyse;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 {private static final String TAG = "ViewAnalyse";public MyLinearLayout(Context context) {super(context);// TODO Auto-generated constructor stub}public MyLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubLog.d(TAG, "dispatchTouchEvent-- action="+ev.getAction()+"--MyLinearLayout");return super.dispatchTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubLog.d(TAG, "onInterceptTouchEvent-- action="+ev.getAction()+"--MyLinearLayout");return super.onInterceptTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubLog.d(TAG, "onTouchEvent-- action="+event.getAction()+"--MyLinearLayout");return super.onTouchEvent(event);}}

MyButton.java

package com.example.viewanalyse;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.view.MotionEvent;import android.widget.Button;public class MyButton extends Button {    private static final String TAG = "ViewAnalyse";    public MyButton(Context context) {super(context);// TODO Auto-generated constructor stub}public MyButton(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubLog.d(TAG, "onTouchEvent-- action="+event.getAction()+"--MyButton");return super.onTouchEvent(event);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {Log.d(TAG, "dispatchTouchEvent-- action="+event.getAction()+"--MyButton");// TODO Auto-generated method stubsuper.dispatchTouchEvent(event);return true;}}

布局文件activity_main.xlm

<com.example.viewanalyse.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:id="@+id/layout"    tools:context=".MainActivity" >    <com.example.viewanalyse.MyButton        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/button"        android:text="button" /></com.example.viewanalyse.MyLinearLayout>

MainActivity.java

package com.example.viewanalyse;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.widget.Button;import android.widget.LinearLayout;import android.widget.RelativeLayout;public class MainActivity extends Activity implements View.OnTouchListener,View.OnClickListener {private MyLinearLayout mLayout;    private Button mButton;    private static final String TAG = "ViewAnalyse";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mLayout =(MyLinearLayout)findViewById(R.id.layout);        mButton =(MyButton)findViewById(R.id.button);                mLayout.setOnTouchListener(this);        mButton.setOnTouchListener(this);        mLayout.setOnClickListener(this);        mButton.setOnClickListener(this);            }@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubLog.d(TAG, "onTouch-- action="+event.getAction()+" --"+v);return false;}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubLog.d(TAG, "onClick --"+v);}    }

1.1 我们用手指点击一下button,打印出来的log:

10-16 11:32:41.410: D/ViewAnalyse(10616): dispatchTouchEvent-- action=0--MyLinearLayout10-16 11:32:41.410: D/ViewAnalyse(10616): onInterceptTouchEvent-- action=0--MyLinearLayout10-16 11:32:41.410: D/ViewAnalyse(10616): dispatchTouchEvent-- action=0--MyButton10-16 11:32:41.410: D/ViewAnalyse(10616): onTouch-- action=0 --com.example.viewanalyse.MyButton10-16 11:32:41.410: D/ViewAnalyse(10616): onTouchEvent-- action=0--MyButton10-16 11:32:41.460: D/ViewAnalyse(10616): dispatchTouchEvent-- action=1--MyLinearLayout10-16 11:32:41.460: D/ViewAnalyse(10616): onInterceptTouchEvent-- action=1--MyLinearLayout10-16 11:32:41.460: D/ViewAnalyse(10616): dispatchTouchEvent-- action=1--MyButton10-16 11:32:41.460: D/ViewAnalyse(10616): onTouch-- action=1 --com.example.viewanalyse.MyButton10-16 11:32:41.460: D/ViewAnalyse(10616): onTouchEvent-- action=1--MyButton10-16 11:32:41.470: D/ViewAnalyse(10616): onClick --com.example.viewanalyse.MyButton

1.2 我们用手指点击一下除button以外的其他区域(ViewGroup事件派发),打印出来的log:

10-16 11:35:04.260: D/ViewAnalyse(10616): dispatchTouchEvent-- action=0--MyLinearLayout10-16 11:35:04.260: D/ViewAnalyse(10616): onInterceptTouchEvent-- action=0--MyLinearLayout10-16 11:35:04.260: D/ViewAnalyse(10616): onTouch-- action=0 --com.example.viewanalyse.MyLinearLayout10-16 11:35:04.260: D/ViewAnalyse(10616): onTouchEvent-- action=0--MyLinearLayout10-16 11:35:04.320: D/ViewAnalyse(10616): dispatchTouchEvent-- action=1--MyLinearLayout10-16 11:35:04.320: D/ViewAnalyse(10616): onTouch-- action=1 --com.example.viewanalyse.MyLinearLayout10-16 11:35:04.320: D/ViewAnalyse(10616): onTouchEvent-- action=1--MyLinearLayout10-16 11:35:04.330: D/ViewAnalyse(10616): onClick --com.example.viewanalyse.MyLinearLayout

由Log1.1 我们可以发现,点击一下button,首先触发的是Linearlayout中的dispatchTouchEvent() -->LinearLayout中的onInterceptTouchEvent,然后才是button的dispatchTouchEvent()方法(其中button的事件分发流程就是和上篇View中的分发流程一样)。也就是说,点击一个View事件,首先触发的是父控件的dispatchTouchEvent() -->onInterceptTouchEvent -->然后再传递给子控件进行派发,即子控件的dispatchTouchEvent() .....

由Log1.2 我们可以发现,点击ViewGroup的事件派发和点击View的事件派发有一点差异。差异点主要在在action_down的时候,ViewGroup多了一个onInterceptTouchEvent()方法:

ViewGroup事件顺序为:dispatchTouchEvent->onInterceptTouchEvent->onTouch->onTouchEvent

View事件顺序为:dispatchTouchEvent->onTouch->onTouchEvent

在action_up的时候,LinearLayout却没有触发onInterceptTouchEvent(), 和View的事件派发流程一致。


二。ViewGroup.java传递事件源码分析

0 0
原创粉丝点击