Android基础之事件分发

事件分发的小案例

mRV.setOnTouchListener((v, event) -> {
    Log.e("试图传递","布局  onTouch");
      return false;
});

mRV.setOnClickListener(v -> Log.e("试图传递","布局  OnClick"));

mBtn.setOnTouchListener((v, event) -> {
     Log.e("试图传递","按钮 onTouch");
     return false;
 });

mBtn.setOnClickListener(v -> Log.e("试图传递","按钮  OnClick"));

MyDvRelativeLayout.xml

public class MyDvRelativeLayout extends RelativeLayout {
    public MyDvRelativeLayout(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("事件分发","父ViewGroup dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e("事件分发","父ViewGroup onInterceptTouchEvent   "+super.onInterceptTouchEvent(ev));
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("事件分发","父ViewGroup onTouchEvent");
        return super.onTouchEvent(event);
    }
}

MyButton.xml

public class MyButton extends android.support.v7.widget.AppCompatButton {
    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.e("事件分发","子View dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("事件分发","子View onTouchEvent 返回: "+super.onTouchEvent(event) +" 触摸状态 "+event.getAction() );
        return super.onTouchEvent(event);
    }

}

点击按钮运行结果:

如下图可以发现:布局并未响应点击事件,事件的流向打印如下:

07-19 14:01:54.354 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:01:54.354 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:01:54.354 15257-15257/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:01:54.356 15257-15257/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 0
07-19 14:01:54.426 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:01:54.426 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:01:54.426 15257-15257/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:01:54.427 15257-15257/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 1

按钮的响应如下,只触发了按钮的事件,正如上图所示,由于子view的onTouchEvent( )返回了true了,那么就意味着触摸事件已经被消费了,那么就不会返回给父控件再进行处理了 

07-19 14:04:04.141 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:04:04.199 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:04:04.200 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 OnClick
07-19 14:04:04.201 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 OnClick

合起来如下:

07-19 14:06:49.395 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:06:49.395 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:06:49.395 15257-15257/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:06:49.395 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:06:49.397 15257-15257/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 0
07-19 14:06:49.434 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:06:49.434 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:06:49.434 15257-15257/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:06:49.434 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:06:49.434 15257-15257/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 2
07-19 14:06:49.483 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:06:49.483 15257-15257/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:06:49.483 15257-15257/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:06:49.483 15257-15257/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:06:49.484 15257-15257/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 1
07-19 14:06:49.484 15257-15257/com.example.mydairytestproject E/试图传递: 按钮  OnClick
07-19 14:06:49.487 15257-15257/com.example.mydairytestproject E/试图传递: 按钮  OnClick

当MyButton的 onTouchEvent()如下返回false时,打印日志如下

@Override
public boolean onTouchEvent(MotionEvent event) {
   Log.e("事件分发","子View onTouchEvent 返回: "+super.onTouchEvent(event) +" 触摸状态 "+event.getAction() );
   return false;
}
07-19 14:12:26.425 18319-18319/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:12:26.425 18319-18319/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   false
07-19 14:12:26.425 18319-18319/com.example.mydairytestproject E/事件分发: 子View dispatchTouchEvent
07-19 14:12:26.426 18319-18319/com.example.mydairytestproject E/试图传递: 按钮 onTouch
07-19 14:12:26.427 18319-18319/com.example.mydairytestproject E/事件分发: 子View onTouchEvent 返回: true 触摸状态 0
07-19 14:12:26.427 18319-18319/com.example.mydairytestproject E/试图传递: 布局  onTouch
07-19 14:12:26.427 18319-18319/com.example.mydairytestproject E/事件分发: 父ViewGroup onTouchEvent
07-19 14:12:26.496 18319-18319/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:12:26.496 18319-18319/com.example.mydairytestproject E/试图传递: 布局  onTouch
07-19 14:12:26.496 18319-18319/com.example.mydairytestproject E/事件分发: 父ViewGroup onTouchEvent
07-19 14:12:26.497 18319-18319/com.example.mydairytestproject E/试图传递: 布局  OnClick

onTouchEvent()小结

点击事件是在手指抬起时触发的,只有OnTouchEvent()默认一般情况下是返回true的,意味着事件被该控件(布局)给消费了,如果返回 false 那么意味着无法消费,那么就不得不交给父布局处理。

接下啦来把父视图的 onInterceptTouchEvent( )返回 true,即拦截事件看看,Button啥都没调用

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
      return true;
 }
07-19 14:25:00.493 21372-21372/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:25:00.493 21372-21372/com.example.mydairytestproject E/事件分发: 父ViewGroup onInterceptTouchEvent   true
07-19 14:25:00.493 21372-21372/com.example.mydairytestproject E/试图传递: 布局  onTouch
07-19 14:25:00.493 21372-21372/com.example.mydairytestproject E/事件分发: 父ViewGroup onTouchEvent
07-19 14:25:00.563 21372-21372/com.example.mydairytestproject E/事件分发: 父ViewGroup dispatchTouchEvent
07-19 14:25:00.564 21372-21372/com.example.mydairytestproject E/试图传递: 布局  onTouch
07-19 14:25:00.564 21372-21372/com.example.mydairytestproject E/事件分发: 父ViewGroup onTouchEvent
07-19 14:25:00.565 21372-21372/com.example.mydairytestproject E/试图传递: 布局  OnClick

猜你喜欢

转载自blog.csdn.net/crazyZhangxl/article/details/81113907