废话不说先上代码
布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.example.cc.eventdemo.MyRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.cc.eventdemo.MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"
android:textAllCaps="false"/>
<com.example.cc.eventdemo.MyButton
android:id="@+id/mybtn"
android:textAllCaps="false"
android:text="mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
</com.example.cc.eventdemo.MyButton>
</com.example.cc.eventdemo.MyRelativeLayout>
两个自定义view的代码
自定义MyButton
public class MyButton extends Button {
public MyButton(Context context) {
this(context,null);
}
public MyButton(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d("123", "dispatchTouchEvent:MyButton: "+event.getAction());
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("123", "onTouchEvent: MyButton:"+event.getAction());
return super.onTouchEvent(event);
}
}
自定义RelativeLayout
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.d("123", "dispatchTouchEvent: MyRelativeLayout:"+ev.getAction());
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("123", "onInterceptTouchEvent: MyRelativeLayout:"+ev.getAction());
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("123", "onTouchEvent: MyRelativeLayout:"+event.getAction());
return super.onTouchEvent(event);
}
}
MainActivity代码
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnClickListener {
private MyButton mMyButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
MyRelativeLayout parent = findViewById(R.id.parent);
mMyButton = findViewById(R.id.mybtn);
button.setOnTouchListener(this);
parent.setOnTouchListener(this);
button.setOnClickListener(this);
parent.setOnClickListener(this);
mMyButton.setOnTouchListener(this);
mMyButton.setOnClickListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("123", "onTouch,View" + v + ",Action:" + event.getAction());
return false;
}
@Override
public void onClick(View v) {
Log.d("123", "onClick,View" + v);
}
}
点击mybutton运行打印结果:
结论:父容器先拿到down事件分别调用dispatchTouchEvent向下分发,onInterceptTouchEvent拦截事件此时不拦截,向子view(MyButton)分发down事件,MyButton获取down事件调用onTouch,再调onTouchEvent方法响应down事件.当松开手指父容器先获取up事件,执行顺序跟down事件一样,如果MyButton设置了点击事件会调用onClick