Android 事件分发机制

在结合资料和项目开发过程中遇到的问题(更多好内容戳下面:https://blog.csdn.net/wuqingsen1),下面是本人对 Android 事件分发机制的了解:

1. 事件分发的对象是谁?

   答:点击事件( Touch 事件 )。Touch 事件的相关细节(发生触摸的位置、时间等)被封装成 MotionEvent 对象。

2.事件的类型分为几种?

   答:分为四种,具体如下表;

事件类型具体动作
MotionEvent.ACTION_DOWN按下 View (所有事件的开始)
MotionEvent.ACTION_UP抬起 View
MotionEvent.ACTION_MOVE滑动 View
MotionEvent.ACTION_CANCEL结束事件 (非人为原因)

3.事件列:手指触摸屏幕到离开屏幕这个过程产生的一系列事件如下;

3.事件在哪些对象之间进行传递?

   答:Activity、ViewGroup、View( Android 的 UI 界面 Activity、ViewGroup、View 以及派生类组成)。

4.事件的分发顺序?

   答:即事件的传递顺序:Activity ==> ViewGroup ==> View 。

5.事件分发过程由哪些主要方法协作完成?

   答:dispatchTouchEvent()、onInterceptTouchEvent() 和 onTouchEvent() 。( 下面是对三个方法的介绍 )

方法名称作用调用时刻
dispatchTouchEvent()分发事件分发传递事件当点击事件能够传递给当前 View 时,该方法会被调用
onInterceptTouchEvent()拦截事件

判断是否拦截了事件;

默认返回 false 表示不拦截该事件,事件将向下传递(传递给其子View);
若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递,
事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法

在 dispatchTouchEvent() 内部调用
onTouchEvent()触摸事件

处理点击事件;

返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);
返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理

在 ViewGroup 的 dispatchTouchEvent() 内部调用;

   下面是拥有这三个方法的对象:

对象名称例子方法名称
ActivityActivity

dispatchTouchEvent(); 

onTouchEvent();

ViewGroupLinearLayoutdispatchTouchEvent();
onInterceptTouchEvent();
onTouchEvent();
ViewTextViewdispatchTouchEvent();
onTouchEvent();

6.工作流程的总结:

7.核心方法的总结:

8.Demo(demo下载地址https://download.csdn.net/download/wuqingsen1/10635286):

//Activity 即第一层
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第一层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第一层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第一层" + "往下分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第一层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第一层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean t = false;
        Log.e("e", "第一层" + "能解决吗" + t);
        return t;
    }
}
//ViewGroup 即第二层
public class MyLinearLayout extends LinearLayout {

    public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第二层" + "往下分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 onInterceptTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 onInterceptTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第二层" + "需要拦截吗" + b);
        return b;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("e", "第二层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e", "第二层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第二层" + "能解决吗" + b);
        return b;
    }
}
//View 即第三层
@SuppressLint("AppCompatCustomView")
public class MyTextView extends TextView{

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("e","第三层 dispatchTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e","第三层 dispatchTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        Log.e("e", "第三层"+"往下分派事件?我是最底层,没有办法分派事件");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.e("e","第三层 onTouchEvent ACTION_DOWN");
                break;
            case MotionEvent.ACTION_UP:
                Log.e("e","第三层 onTouchEvent ACTION_UP");
                break;
            default:
                break;
        }
        boolean b = false;
        Log.e("e", "第三层"+"能解决吗"+b);
        return b;
    }
}

下面是分发走的顺序:

至此,应该对事件分发机制有一定了解,demo下载地址https://download.csdn.net/download/wuqingsen1/10635286

如果有更好的见解或补充点下面喔:

https://blog.csdn.net/wuqingsen1

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值