View的事件体系

来源:互联网 发布:java 画流程图 插件 编辑:程序博客网 时间:2024/05/10 03:13

一、View基础知识


1、View的概念

View是对界面层控件的一种抽象,它代表了一个控件。除了View,还有ViewGroup,ViewGroup继承自View,表示由多个控件组成的一组控件,也就是说,View既可以表示一个控件,也可以表示由多个控件组成的一组控件。

2、View的位置参数

1)left:View左边到父布局左边的距离
2)right:View右边到父布局左边的距离
3)top:View上边到父布局上边的距离
4)bottom:View下边到父布局上边的距离

Android 3.0新增的参数
1)x、y:View左上角的坐标
2)translationX、translationY:View左上角相对于父容器的偏移量

3、View的主要相关类

1)MotionEvent的事件类型
-ACTION_DOWN:手指刚接触屏幕
-ACTION_MOVE:手指在屏幕上移动

-ACTION_UP:手指从屏幕上松开


2)TouchSlop

系统能识别的被认为是滑动的最小距离。通过ViewConfiguration.get(getContext()).getScaledTouchSlop()获取这个常量。


3)VelocityTracker
追踪手指在滑动过程中的速度,包括水平和竖直速度。

注意:

  • 调用getXVelocity/getYVelocity之前,必须调用computeCurrentVelocity(x)来计算x ms内滑过的像素数。
  • 当不需要用它时,调用clear()和recycle()来进行重置和回收。
4)GestureDetector
手势检测,用于检测用户的单击、双击、滑动等行为
实现:
  • -创建一个GestureDetector对象并实现OnGestureListener接口,根据需要还可以实现OnDoubleTapListener接口来监听双击行为
  • -在待监听View的onTouchEvent方法中,调用GestureDetector.onTouchEvent方法。
  • -最后有选择地实现OnGestureListener、OnDoubleTapListener中的方法。
  1.     onDown:手指轻触屏幕的一瞬间。
  2.     onShowPress:手指轻触屏幕,尚未松动或者拖动。
  3.     onSingleTapUp:单击行为。
  4.     onScroll:拖动行为。
  5.     onLongPress:长按行为。
  6.     onFling:快速滑动行为。
  7.     onDoubleTap:双击行为。
  8.     onSingleTapConfirmed:严格的单击行为,而不可能是双击。
  9.     onDoubleTapEvent:双击行为。


5)Scroller
弹性滑动对象,它本身无法让View弹性滑动,需要和View的computeScroll方法配合使用。

二、View的滑动


1、使用scrollTo、scrollBy

scrollBy调用了scrollTo,实现了基于当前位置的相对滑动,scrollTo实现了基于所传递参数的绝对滑动。使用scrollTo、scrollBy只能移动View的内容,不能移动它的位置。

2、使用动画

可以采用传统的View动画,也可以采用属性动画,如果采用属性动画,为了兼容3.0以下的版本,需要采用开源动画库nineoldandroids,为了保留动画后的状态,可以将fillAfter属性设置为true。

3、改变布局参数

通过设置LayoutParams里的参数实现动画的效果。

三者的比较:
  • 1)scroll、scrollBy:操作简单,适合对View内容的滑动。
  • 2)动画:操作简单,主要适用于没有交互的View和实现复杂的动画效果。
  • 3)改变布局参数:操作复杂,适用于有交互的View。

三、弹性滑动


1、使用Scroller

1)在startScroll方法后面调用invalidate方法,可以导致View重绘。
2)Scroller并不能实现View的滑动,它需要配合View的computeScroll方法才能完成弹性滑动的效果,它不断地让View重绘,而每一次重绘距滑动起始时间会有一个间隔,通过这个间隔就可以得出View当前地滑动位置,知道了滑动位置就可以通过scrollTo完成滑动。

2、通过动画

实现AnimatorUpdateListener接口,根据动画每一帧到来时获取动画完成的比例,计算要滑动的距离,调用scrollTo方法实现滑动。

3、使用延时策略

通过发送一系列延时消息,达到渐近式的效果。

四、View的事件分发机制


1、事件传递的主要方法

1)dispatchTouchEvent:负责事件的分发
2)onInterceptTouchEvent:判断是否拦截某个事件
3)onTouchEvent:消费点击事件

2、事件的传递规则


遵循的顺序:Activity->Window->DecorView->顶层View->子View

  1. 同一个时间序列指从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,这个过程所产生的一系列事件。
  2. 某个View一旦决定拦截,那么这一个事件序列只能由它处理,并且它的onInterceptTouchEvent不会再被调用。
  3. 某个View一旦决定开始处理事件,如果它不消耗ACTION_DOWN事件,那么同一时间序列中的其他事件都不会交给它处理,并且事件将交给它的父元素去处理。
  4. 如果View只消耗ACTION_DOWN事件,那么这个点击事件就会消失,父元素的onTouchEvent不会被调用,而且当前View可以持续收到后续事件,最终这些消失的事件会传递给Activity处理。
  5. ViewGroup默认不拦截任何事件。
  6. View没有onInterceptTouchEvent方法,一旦点击事件传递给它,那么它的onTouchEvent方法就会被调用。
  7. View的onTouchEvent默认都会消耗事件,除非他是不可点击的。
  8. View的enable属性不影响onTouchEvent的默认返回值。
  9. onClick发生的前提是当前View可点击,而且接收到了ACTION_DOWN和ACTION_UP事件。
  10. 事件传递由外向内,在子元素中可以通过requestDisallowInterceptTouchEvent方法干预父元素的分发过程。

五、滑动冲突


1、典型场景

1)外部和内部的滑动方向不一致
2)外部和内部的滑动方向一致
3)上面两种情况的嵌套

2、解决方式

1)外部拦截法:点击事件都先经过父容器的拦截,如果父容器需要此事件就拦截,否则向下传递。
2)内部拦截法:父容器不拦截任何事件,所有的事件都交传递给子元素,如果子元素需要此事件就消耗掉,否则交由父容器处理。

0 0