zoukankan      html  css  js  c++  java
  • View的事件分发机制

     /********************************************************************************************************
     * view.java源码中的scrollTo(),
     * mScrollX是view布局左边缘和view内容左边缘的水平距离
     * mScrollY是view布局上边缘与view内容上边缘的垂直距离
     * x,y是view左上角的坐标,translationX,为相对于父容器偏移的距离。
     * x=left+translationX;y=top+translationY
     * getx/gety返回相对当前view左上角的坐标
     * getRawx/getRawY返回相对于屏幕左上角的坐标。。
     ********************************************************************************************************/
     
      public void scrollTo(int x, int y) {
            if (mScrollX != x || mScrollY != y) {
                int oldX = mScrollX;
                int oldY = mScrollY;
                mScrollX = x;
                mScrollY = y;
                invalidateParentCaches();
                onScrollChanged(mScrollX, mScrollY, oldX, oldY);
                if (!awakenScrollBars()) {
                    postInvalidateOnAnimation();
                }
            }
        }
     
     /********************************************************************************************************
     * view.java源码中的scrollBy(),
     *  从源码可以看出两个的不同,scrollto是滑动到指定位置,而scrollBy是指定参数滑动距离
     ********************************************************************************************************/
     public void scrollBy(int x, int y) {
            scrollTo(mScrollX + x, mScrollY + y);
        }
    /***************************************************************************************
    *两个方法只能改变view内容的位置不能改变view在布局中的位置,当view是容器的时候,其内部的组件点击事件不会被影响
    view布局左边缘在view内容左边缘右边的时候mscrollX为正(内容向左滑为正)
    view布局上边缘在view内容上边缘下面的时候mscrollY为正(内容向上滑为正)
    *
    *
    *三种实现view滑动的方式:
    *   1.scrollTo()/scrollBy();
            这种方式只能滑动view的内容,不能滑动view本身的位置,不会影响内容的点击事件
        2.view动画,改变translationX,translationY的方式
            这种方式可以做出很复杂的滑动效果但是会影响view内容的交互
            android3.0以上的版本可以不影响点击事件。。
        3.改变Layoutparams
            marginLeft+=xxx实现向右滑。。
    **************************************************************************************//*
    view的弹性滑动:在一段时间内实现若干小的滑动,比较生硬
    **************************************************************************************/、
    /*view的事件分发机制
        onDispatchTouchEvent()分发事件
        onIntercepetTouchEvent()是否拦截该事件,拦截后交给ontouchevent处理
        onTouchEvent()处理事件
    *某个motionEvent发生,根view的onDispatchTouchEvent()就会被调用,该方法内部的onInterceptTouch()决定是否
        * 拦截这个事件,如果拦截就交给onTouchEvent()处理,若果不拦截就交由子view处理,调用子view的OnDispatchTouchEvent()分发。。
            *直到被拦截处理。。。。
     
    *某个view继承了OnTouchListener,在发生touchEvent的时候会先调用OnTouchListener中的onTouch()方法,该方法返回一哥boolean值,为true表示
    在OnTouchListener中处理,为falsh会调用onTouchEvent()处理事件。由此可见OnTouchListener优先级比onTouchEvent()高,而onTouchEvent中
    有onClick()方法,只有经过上述过程最后才能进入这个方法处理点击事件,故而优先级最低。
    Activity>>Window>>View--onDispatchTouchEvent(){onInterceptTouchEvent(){onTouchEvent}},
    <<           <<   onTouchEvent()    <<          <<       <<     <<onTouchEvent.return false
    事件的传递过程总是由外向内的。。。。事件先传递给父元素再传递给子元素。。
     
     
    &&这个过程的相关概念:
    事件序列:从ActionDown开始 ---Actionmove---Actionmove--Actionmove。。。Actionup结束
    一个事件序列只能被view拦截消耗,意思是说比如某个view的onInterceptTouchEvent()拦截了一个ActionDown事件,那么
    后面该序列的其他时间都交由它处理,当然也可以通过特殊方法传递给其他的view处理,但是从本质上来说还是它处理的只是它把球传给其他人,球还是它的。
    而一旦ActionDown没有被拦截即onInterceptTouchEvent().return false;该事件序列就不会再处理.onInterceptTouchEvent()默认不拦截,onTouchEvent()默认拦截
    ******************************************************************************************************************************************/
     /*************************************************************************************************************************
     *
     *关于ViewGroup的分发事件即DIspatchTouchEvent()需要补充说明的是,这个方法通过if语句根据条件决定是否要拦截事件,每一个ActionDown事件到来都会
     *判断是否拦截。当他自己不拦截,而把这个ActionDown交由子View拦截时,在这个序列的其他事件ActionMove ActionUp发生时,都会进入dispatchTouchEvent的方法
     *中去判断一次是否要拦截。也就是说一个序列中的事件,子view拦截处理了一部分,上层的View/ViewGroup还有权利决定是否要拦截,这些一个序列的事件是分开独立的。
     *如果父类拦截了序列事件第一个事件ActionDown,那么紧随这个事件后面的同一个序列的其他事件都会被viewgroup处理。
     *但是呢话虽然这么说,看起来viewgroup权利很大,子View有相应的制衡手段,可以通过子view的requestDisallowInterceptTouchEvent()设置FLAG_DISALLOW_INTERCEPT标志位影响父view的拦截
     *看源程序好理解一些。。。(这个标志位会在每次ActionDown事件发生时刷新重置,也就是说子view的并不会影响(屏蔽)父view对于Action
     Down的拦截。)
     *
     ************************************************************************************************************************/
  • 相关阅读:
    不同地区Android开发者使用哪些设备测试APP?
    IIS6、IIS7.5设置网站默认首页方法(Directory Listing Denied)
    大数据正在改变我们的生活
    如何在MySQL中使用explain查询SQL的执行计划?
    整合spring cloud云架构
    对SQL 优化,提升性能!
    传统分布式架构如何进行容器化升级
    Android开发实践:Android.mk模板
    如何从代码层面优化系统性能
    德国又出超实用的厨房神器
  • 原文地址:https://www.cnblogs.com/geekj/p/8383566.html
Copyright © 2011-2022 走看看