android自定义控件事件的传递

时间:2022-09-20 00:57:05
自定义关键事件的传递(一)       在自定义空间中事件的传递十分重要,为了记录和巩固知识特此记录, 由于水平有限,不对的地方希望可以给小弟指正。       不废话,先上张图 android自定义控件事件的传递
上面这张图描述的是事件的传递,当我们点击button的时候事件上事件的传递是先走的RelativeLayout的触摸事件,之后传递给Button,在Button没有消耗的情况下,还会传递给上一层。    下面上代码验证一下:布局就是一个自定义的相对布局relative里面放置一个自定义的Button,并重写里面的 代码如下:
@SuppressLint("AppCompatCustomView")
public class MyButton extends Button {
private static final String TAG = "lang";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.i(TAG,"Button dispatchTouchEvent");
return super.dispatchTouchEvent(event);
}
}

          因为代码重复,直上一个的代码,运行之后我们查看打印的结果。
android自定义控件事件的传递
这里的dispatchTouchEvent方法就是做事件分发用的,好的我们先岔开话题,讨论一下,View的OnTouch事件和OnClick事件的关系,代码的写法布局上是一样的,不多说先上代码:
  Button button = (Button) findViewById(R.id.btn);
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.i(TAG,"Button onTouch"+motionEvent.getAction());
return true;
}
});

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(TAG,"Button OnClick");
}
});


            运行打印看效果:android自定义控件事件的传递      首先运行的事OnTouch事件,之后才走的OnClick事件,当我们OnTouch返回true的时候,运行看效果:android自定义控件事件的传递我们发现OnClick事件没有响应,原因是没有接收到UP事件。所以我们可以得到以下的结论:1.控件的Listener事件触发的顺序是先onTouch,再onClick。
2.控件的onTouch返回true,将会onClick事件没有了---阻止了事件的传递。
 返回false,才会传递onClick事件(才会传递up事件)
下面我们来讨论,View本身的onTouch事件和Listener事件还有dispatchTouchEvent事件之间的关系:
android自定义控件事件的传递            先贯穿以下顺序,不多说先上代码首先是设置一个touch监听,之后再View中:
@SuppressLint("AppCompatCustomView")
public class MyButton extends Button {
private static final String TAG = "lang";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.i(TAG,"Button dispatchTouchEvent");
return super.dispatchTouchEvent(event);
// return true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG,"Button onTouchEvent");
return super.onTouchEvent(event);
}
}

打印验证事件传递的顺序:android自定义控件事件的传递这个是走的顺序,当我们在android自定义控件事件的传递
这里只返回true的时候,我们运行的效果是android自定义控件事件的传递也就是是说事件会在这里终止,但是,当我们这样的时候:android自定义控件事件的传递效果:android自定义控件事件的传递所以super.dispatchTouchEvent是实际的分发代码,同理,我们的OnTouch也是如此,这里我们就不验证了。但是我们在Listener事件里面返回true的时候呢?当:android自定义控件事件的传递运行的效果是这样的:android自定义控件事件的传递所以我们可以得到这样的结论:
1.如果onTouchListener的onTouch方法返回了true,那么view里面的onTouchEvent就不会被调用了。顺序dispatchTouchEvent-->onTouchListener---return false-->onTouchEvent
2.如果view为disenable,则:onTouchListener里面不会执行,但是会执行onTouchEvent(event)方法

3.onTouchEvent方法中的ACTION_UP分支中触发onclick事件监听
onTouchListener-->onTouch方法返回true,消耗次事件。down,但是up事件是无法到达onClickListener.
onTouchListener-->onTouch方法返回false,不会消耗此事件

后两条结论是通过分析源码所得来的:这里就不分析源码了,可以自己去验证,希望对小伙伴们有帮助。有错的地方可以留言指正。谢谢