笔记:View

View


  • View的left,top,bottom,right对应于源码中的mLeft,mTop,mBottom,mRight,
    是相对于父容器而言的。获取方式,getLeft(),getTop,getRight(),getBottom()

  • 从Android 3.0开始,View增加了几个额外参数,x,y,translationX和translationY,也都是相对于父容器。

x,y是view的左上角坐标
translationX和translationY是相对于父容器的偏移量,默认值为0

关系:x= left+translationX, y=top+translationY


  • 在平移过程中,top和left表示原始左上角坐标的位置,不会发生改变,发生改变的只有x,y,translationX,translationY.

  • 通过MotionEvent可以获得点击事件发生的点的x,y坐标

getX()/getY() 获取相当于当前View左上角的坐标

getRawX()/getRowY() 返回相当于屏幕的左上角的坐标


  • TouchSlop 系统所能识别出的被认为是滑动的最小距离 p125

获取方式:

ViewConfiguration.get(getContext()).getScaledTouchSlop();

  • VelocityTracker 速度追踪,用于追踪手指在滑动过程中的速度。p126

  • GestrueDetector 手势检测,用于辅助检测用户的单击滑动双击长按等行为
    GestrueDetector mGestrueDetector = new GestrueDetector();
    //解决长按屏幕后无法拖动现象
    mGestrueDetector.setIsLongpressEnable(flase);
    
    //接管目标View的onTouchEvent,在onTouchEvent中做如下处理
    boolean consume = mGestrueDetector.onTouchEvent(event);
    return consume;

  • Scroller 弹性滑动对象

需要和View的computeScroll方法配合使用

    
    Scroller scroller = new Scroller(getContext());

    private void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        //1000ms 内滑向 destX,效果就是慢慢滑动
        scroller.startScroll(scrollX, 0, delta, 0, 1000);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate();
        }
    }



  • scrollTo,scrollBy只能改变View的内容位置,而不能改变View在布局中的位置

mScrollX指View左边缘到View内容左边缘的距离,mScrollY同理

View的左边缘在View内容左边缘的右边时,mScrollX值为正(从右向左滑动),View上边缘在View内容上边缘的下边时,mScroll值为正(从下往上滑动)。

获取方式:getScrollX(),getScrollY()


View事件分发机制

笔记:View_第1张图片
View事件分发机制

如果给一个View设置了onTouchListener,那么它的onTouchListener的onTouch方法会被调用,这时就看onTouch的返回值,如果返回false,则当前View的onTouchEvent会被调用,在onTouchEvent中,如果当前view设置有onClickListener,那么它的onClick方法会被调用

由此可见 onTouchListener>onTouchEvent>onClickListenr.


  • requestDisallowInteceptTouchEvent()在子元素干预父元素的事件分发过程

笔记:View_第2张图片
1

笔记:View_第3张图片
2

  • Activity的事件分发过程:

当一个点击事件发生时,事件最新传递给Activity的dispatchTouchEvent,由它来派发事件,具体会由Activity的Window来进行处理,Window会将事件传递给DecorView,decor view一般就是界面的底层容器,

Activity dispatchTouchEvent源码分析:
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

如果返回了true则activity的dispatchTouchEvent也就执行完毕了,如果返回false,则交由activity onTouchEvent处理。

window中的分发是由其实现类phoneWindow来分发的。PhoneWindow直接将事件分发给DecorView(FrameLayout)


  • 顶级容器对事件的分发过程


    笔记:View_第4张图片
    顶级容器对事件的分发过程

  • View的onClick事件执行是在onTouchEvent中的ACTION_UP中执行的。

你可能感兴趣的:(笔记:View)