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实现滑动
offsetLeftAndRight和offsetTopAndBottom实现滑动
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重复如上步骤。