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

来源:互联网 发布:fresh玫瑰化妆水知乎 编辑:程序博客网 时间:2024/05/19 13:42

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}// 是否结束继续派发@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {    Log.e("MainActivity", "经过了ChildView,dispatchTouchEvent---->");    return super.dispatchTouchEvent(ev);}@Overridepublic 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--->005-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--->105-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--->005-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 ——>“事件继续工作”。

Demo例子
如果发现有错,请指导!非常感激!
喜欢的赞一个。

0 0
原创粉丝点击