Android View 事件总结2

01.View滑动有哪些方法

  • View滑动有哪些方法?

    • layout:对View进行重新布局定位。在onTouchEvent()方法中获得控件滑动前后的偏移。然后通过layout方法重新设置。
    • offsetLeftAndRight和offsetTopAndBottom:系统提供上下/左右同时偏移的API。onTouchEvent()中调用
    • LayoutParams: 更改自身布局参数
    • scrollTo/scrollBy: 本质是移动View的内容,需要通过父容器的该方法来滑动当前View
    • Scroller: 平滑滑动,通过重载computeScroll(),使用scrollTo/scrollBy完成滑动效果。
    • 属性动画: 动画对View进行滑动
    • ViewDragHelper: 谷歌提供的辅助类,用于完成各种拖拽效果。
  • Layout实现滑动

    • image
  • offsetLeftAndRight和offsetTopAndBottom实现滑动

    • image
  • LayoutParams实现滑动

    • 通过父控件设置View在父控件的位置,但需要指定父布局的类型,不好

    • 用ViewGroup的MariginLayoutParams的方法去设置margin

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      //方法一:通过布局设置在父控件的位置。但是必须要有父控件, 而且要指定父布局的类型,不好的方法。 
      RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
      layoutParams.leftMargin = getLeft() + offsetX;
      layoutParams.topMargin = getTop() + offsetY;
      setLayoutParams(layoutParams);
      /**===============================================
      * 方法二:用ViewGroup的MarginLayoutParams的方法去设置marign
      * 优点:相比于上面方法, 就不需要知道父布局的类型。
      * 缺点:滑动到右侧控件会缩小
      *===============================================*/
      ViewGroup.MarginLayoutParams mlayoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
      mlayoutParams.leftMargin = getLeft() + offsetX;
      mlayoutParams.topMargin = getTop() + offsetY;
      setLayoutParams(mlayoutParams);
  • scrollTo\scrollBy实现滑动

    • 都是View提供的方法。
    • scrollTo-直接到新的x,y坐标处。
    • scrollBy-基于当前位置的相对滑动。
    • scrollBy-内部是调用scrollTo.
    • scrollTo\scrollBy, 效果是移动View的内容,因此需要在View的父控件中调用。
    • scrollTo/By内部的mScrollX和mScrollY的意义
      • mScrollX的值,相当于手机屏幕相对于View左边缘向右移动的距离,手机屏幕向右移动时,mScrollX的值为正;手机屏幕向左移动(等价于View向右移动),mScrollX的值为负。
      • mScrollY和X的情况相似,手机屏幕向下移动,mScrollY为+正值;手机屏幕向上移动,mScrollY为-负值。
      • mScrollX/Y是根据第一次滑动前的位置来获得的,例如:第一次向左滑动200(等于手机屏幕向右滑动200),mScrollX = 200;第二次向右滑动50, mScrollX = 200 + (-50)= 150,而不是(-50)。
  • 动画实现滑动的方法

    • 可以通过传统动画或者属性动画的方式实现
    • 传统动画需要通过设置fillAfter为true来保留动画后的状态(但是无法在动画后的位置进行点击操作,这方面还是属性动画好)
    • 属性动画会保留动画后的状态,能够点击。
  • ViewDragHelper

    • 通过ViewDragHelper去自定义ViewGroup让其子View具有滑动效果。不过用的很少

02.Activity事件分发过程

  • Activity事件分发的过程?
    • 事件分发过程:Activity->Window->Decor View(当前界面的底层容器,setContentView的View的父容器)->ViewGroup->View
    • Activity的dispatchTouchEvent,会交给Window处理(getWindow().superDispatchTouchEvent()),
    • 返回true:事件全部结束
    • 返回false:所有View都没有处理(onTouchEvent返回false),则调用Activity的onTouchEvent

03.Window事件分发过程

  • Window事件分发?
    • Window和superDispatchTouchEvent分别是抽象类和抽象方法
    • Window的实现类是PhoneWindow
    • PhoneWindow的superDispatchTouchEvent()直接调用mDecor.superDispatchTouchEvent(),也就是直接传给了DecorView

04.DecorView的事件分发

  • DecorView的事件分发?
    • DecorView继承自FrameLayout
    • DecorView的superDispatchTouchEvent()会调用super.dispatchTouchEvent()——也就是ViewGroup的dispatchTouchEvent方法,之后就会层层分发下去。

05.根View的事件分发

  • 根View的事件分发?
    • 顶层View调用dispatchTouchEvent
    • 调用onInterceptTouchEvent方法
    • 返回true,事件由当前View处理。如果有onTouchiListener,会执行onTouch,并且屏蔽掉onTouchEvent。没有则执行onTouchEvent。如果设置了onClickListener,会在onTouchEvent后执行onClickListener
    • 返回false,不拦截,交给子View重复如上步骤。