摘要:
整个事件分发就类似于分发任务是一样的
老大分配任务给老二 、老二分配任务给老三
如果老三完成了,这个任务就结束了,如果老三没有完成则会将任务返回给老二,老二如果解决了,任务也就结束了,如果老二也没有完成则会将任务返回给老大。
通过代码观察:
布局文件:
<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(很好)