Android事件分发机制------------>验证+理解

View的事件分发机制的总结:

MotionEvent:

  1. ACTION_DOWN—手指刚接触屏幕;
  2. ACTION_MOVE—-手指在屏幕上移动;
  3. ACTION_UP——-手机从屏幕上松开的一瞬间;

    点击屏幕离开后松开,事件序列为DOWN->UP;
    点击屏幕滑动一会再松开,事件序列为DOWN->MOVE->….MOVE->UP.

@Api

  1. public boolean dispatchTouchEvent(MotionEvent ev);
    用来进行事件的分发。如果事件能够传递当前View,那么此方法一定会被调用,返回结果当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。
  2. public boolean onInterceptTouchEvent(MotionEvent event);
    用来判断是否拦截某个事件,true–>自行处理,false–>继续向下派发。
  3. public boolean onTouchEvent(MotionEvent event);
    判断是否消费,true–>消费,false–>不消费,继续向上级提交。

总结:
隧道式派发,冒泡式消费。
理解记忆:
派发:Activity—>ViewGroup—–>View
消费:View–>ViewGroup—>Activity

写一个Demo验证理解:
MainActivity:

package com.example.vieweventdemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //提示:MotionEvent.ACTION_DOWN=0;
        Log.e("MainActivity", "触发MainActivityev--->"+ev.getAction());
         return super.dispatchTouchEvent(ev);
    }
}

再写一个FatherView

package com.example.vieweventdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class FatherView extends RelativeLayout {

    public FatherView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

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

    public FatherView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
    }
    //是否结束继续派发
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("MainActivity", "经过了FatherView,dispatchTouchEvent---->");
         return super.dispatchTouchEvent(ev);
    }
    //判断是否拦截--》true:拦截,false继续派发
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e("MainActivity", "经过了FatherView,onInterceptTouchEvent---->");
        return super.onInterceptTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("MainActivity", "经过了FatherView,onTouchEvent---->");
        return super.onTouchEvent(event);
    }

}

最后一个ChildView
package com.example.vieweventdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

public class ChildView extends TextView {

public ChildView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

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

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

// 是否结束继续派发
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.e("MainActivity", "经过了ChildView,dispatchTouchEvent---->");
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.e("MainActivity", "经过了ChildView,onTouchEvent---->消费了");
    return true;
}

}

布局文件:
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/real"
    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.vieweventdemo.MainActivity" >

    <com.example.vieweventdemo.FatherView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:background="#0f0" >

        <com.example.vieweventdemo.ChildView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:text="textview"
            android:layout_gravity="center"
            android:background="#f00" />

    </com.example.vieweventdemo.FatherView>

</RelativeLayout>


----------
第一种情况。。。最底层view消费了事件

05-02 08:56:36.416: E/MainActivity(1792): 触发MainActivityev--->0
05-02 08:56:36.416: E/MainActivity(1792): 经过了FatherView,dispatchTouchEvent---->
05-02 08:56:36.420: E/MainActivity(1792): 经过了FatherView,onInterceptTouchEvent---->
05-02 08:56:36.420: E/MainActivity(1792): 经过了ChildView,dispatchTouchEvent---->
05-02 08:56:36.420: E/MainActivity(1792): 经过了ChildView,onTouchEvent---->消费了
05-02 08:56:36.532: E/MainActivity(1792): 触发MainActivityev--->1
05-02 08:56:36.532: E/MainActivity(1792): 经过了FatherView,dispatchTouchEvent---->
05-02 08:56:36.532: E/MainActivity(1792): 经过了FatherView,onInterceptTouchEvent---->
05-02 08:56:36.532: E/MainActivity(1792): 经过了ChildView,dispatchTouchEvent---->
05-02 08:56:36.532: E/MainActivity(1792): 经过了ChildView,onTouchEvent---->消费了

第二种情况:最底层view不消费事件。

05-02 09:05:09.821: E/MainActivity(1873): 触发MainActivityev--->0
05-02 09:05:09.821: E/MainActivity(1873): 经过了FatherView,dispatchTouchEvent---->
05-02 09:05:09.821: E/MainActivity(1873): 经过了FatherView,onInterceptTouchEvent---->
05-02 09:05:09.821: E/MainActivity(1873): 经过了ChildView,dispatchTouchEvent---->
05-02 09:05:09.821: E/MainActivity(1873): 经过了ChildView,onTouchEvent---->不消费
05-02 09:05:09.821: E/MainActivity(1873): 经过了FatherView,onTouchEvent---->
05-02 09:05:09.945: E/MainActivity(1873): 触发MainActivityev--->1

其他情况不试了。
总结:
隧道式分发,冒泡式消费。
换角度,以下是个人理解。
return true ——>“事件停止工作”。
return false ——>“事件继续工作”。

Android事件分发机制------------>验证+理解_第1张图片
如果发现有错,请指导!非常感激!
喜欢的赞一个。

你可能感兴趣的:(android)