android学习笔记

android事件分发学习笔记

2020-03-22  本文已影响0人  heheworld
  1. 事件分发的载体主要有 activity,viewgroup,view。
  2. 事件分发的主要方法有 dispatchTouchEvent (事件分发),onInterceptTouchEvent(事件拦截),onTouchEvent(事件响应),
    • 关于返回值

    是boolean类型,如果返回true,表示事件被消费,不再往下一级传递,否则继续传递。如果都没有消费,最终会回到activity的onTouchEvent。

    • 关于onInterceptTouchEvent

    是viewgroup所特有的。

  3. 事件分发的对象是 MotionEvent 。
  4. 事件的序列,常见的就是action_down,move,up,cancel等等,
  1. 事件分发的流程 从activity的dispatchTouchEvent开始,经过phonewindow,decorview,调用到viewgroup的dispatchTouchEvent方法,然后在这个方法里,根据Intercept的值,事件的action,以及对应的childview(根据点击的坐标,从上至下的顺序 获取Z坐标上的view的列表,再依据view的dispatchTouchEvent返回值,返回愿意消费此事件的childview),事件就这样被传递出去。
    例子,viewgroup如果拦截某事件,则直接调用viewgroup的onTouchEvent,
    如果不拦截某事件,则交由子view处理,调用子view的dispatchTouchEvent,然后再调用子view的onTouchEvent。
  2. 关于触摸事件跟点击事件的冲突,如果onTouchEvent 返回true 则事件被消费,不会再响应点击事件。只有返回false,才可以。
  3. 关于滑动冲突,可以通过外部拦截和内部拦截两种方式。
外部拦截,

重写父view的onInterceptTouchEvent 方法
伪代码

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        boolean intercept = false;
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                intercept = false;
                break;
                case MotionEvent.ACTION_MOVE:
                    if(需要拦截)
                    {
                        intercept = true;
                    }
                    else
                    {
                        intercept = false;
                    }
                    break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }
    }
内部拦截,

重写子view的dispatchTouchEvent方法,设置父viewgroup的requestDisallowInterceptTouchEvent 的参数来做控制,
伪代码如下:

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                parent.requestDisallowInterceptTouchEvent(false);
                break;
            case MotionEvent.ACTION_MOVE:
                if(父类容器需要拦截)
                {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
                else
                {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                
                break;
        }
        boolean flag = super.dispatchTouchEvent(ev);
        return flag;
    }
上一篇下一篇

猜你喜欢

热点阅读