android 事件分发机制详解

摘要:
整个事件分发就类似于分发任务是一样的
老大分配任务给老二 、老二分配任务给老三
如果老三完成了,这个任务就结束了,如果老三没有完成则会将任务返回给老二,老二如果解决了,任务也就结束了,如果老二也没有完成则会将任务返回给老大。
这里写图片描述

通过代码观察:
布局文件:

<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">

    <net.fredericosilva.showtipsviewsample.MyRelativeLayout
        android:id="@+id/my_relative"
        android:layout_width="500dp"
        android:layout_height="500dp"
        android:background="#000000"
        >
        <net.fredericosilva.showtipsviewsample.MyButton
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="58dp"
            android:layout_marginTop="36dp"
            android:background="#FF0000"
            android:text="Button1" />

        <net.fredericosilva.showtipsviewsample.MyButton
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/button1"
            android:layout_marginLeft="58dp"
            android:layout_marginTop="36dp"
            android:background="#FF0000"
            android:text="Button2" />
    </net.fredericosilva.showtipsviewsample.MyRelativeLayout>


</RelativeLayout>

MainActivity.java:

package net.fredericosilva.showtipsviewsample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

import net.frederico.showtipsview.ShowTipsBuilder;
import net.frederico.showtipsview.ShowTipsView;

/**
 * 注意事件分发只在具有布局包含关系才具有事件传递的机制。
 * */
public class MainActivity extends Activity {

    private Button btn1;
    private MyRelativeLayout rel1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn1 = (Button) this.findViewById(R.id.button1);
        rel1 = (MyRelativeLayout) this.findViewById(R.id.my_relative);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("test","btn1 click");
            }
        });
        rel1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.i("test","rel1 click");
            }
        });


    }



    /**
     * activity的dispatchTouchEvent
     *
     * */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("test","MainActivity dispatchTouchEvent      "+ev);
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("test","MainActivity onTouchEvent          "+event);
        return super.onTouchEvent(event);
    }





}

MyRelativeLayout.java:

package net.fredericosilva.showtipsviewsample;

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

/**
 * Created by weizhi on 2016/8/23.
 */
public class MyRelativeLayout extends RelativeLayout {
    public MyRelativeLayout(Context context) {
        super(context);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("test","MyRelativeLayout dispatchTouchEvent      "+ev);

        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.i("test","MyRelativeLayout onInterceptTouchEvent         "+ev);
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("test","MyRelativeLayout onTouchEvent         "+event);
        return false;
    }
}

MyButton.java:

package net.fredericosilva.showtipsviewsample;

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

/**
 * Created by weizhi on 2016/8/24.
 */
public class MyButton extends Button {
    public MyButton(Context context) {
        super(context);
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        Log.i("test","MyButton dispatchTouchEvent         "+event);
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        Log.i("test","MyButton onTouchEvent         "+event);
        return true;
    }
}

注意:
1、事件分发只是针对布局之间具有包含关系的。
2、重写控件之后,控件的点击事件是否存在了?
解答:如果这个控件的事件没有被上层拦截掉,另外没有对onTouchEvent方法进行重写,则他的点击事件是有效的,否则点击事件无效。
3、其实事件分发就像一个U形一样,从activity开始一直往下分发,然后从最底层往上分发。当然这个任何一个节点事件都有可能被拦截的。具体拦截后流程怎么走看上面的图。(这里的代码中就是activity->MyRelativeLayout->MyButton->MyRelativeLayout->activity).
4、若在向下传递的过程中被拦截了,即onInterceptTouchEvent方法返回true,则事件将停止向下传递,直接由当前的onTouchEvent方法来处理,若处理成功则OK,若处理不成功,则事件会向上传递。

参考:http://www.open-open.com/lib/view/open1422428386548.html
http://blog.csdn.net/awangyunke/article/details/22047987
http://blog.csdn.net/xyz_lmn/article/details/12517911(很好)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值