Android开发艺术探索(三)——View事件

  本篇将涉及到View的位置参数(left、right、top、buttom、x、y、translationX、translationY)、滑动(Scroller)速度(VelocityTracker)、手势(GestureDetector)、事件触发机制。

View基础

View与ViewGroup

  ViewGroup继承自View,因此View本身可以是单个控件也可以是一组控件,而ViewGroup内部又可以包含View或ViewGroup。

View的位置参数

1
2
3
4
left = getLeft();
right = getRight();
top = getTop();
buttom = getButtom();
View的位置坐标和父容器的关系
1
2
x = left + translationX;
y = top + translationY;
  • x,y : View左上角的坐标
  • translationX,translationY : View左上角相对于父容器的偏移量

MotionEvent

在手指接触屏幕所产生的一系列事件中,典型事件如下:

  • ACTION_DOWN——手指刚接触屏幕
  • ACTION_MOVE——手指滑动
  • ACTION_UP——手指离开屏幕

TouchSlop

系统所能识别出的最小滑动距离,获取方式如下:

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

源码中为8dp

速度追踪VelocityTracker

用于追踪手指的滑动速度,使用方法如下:

 1. 在View的onTouchEvent中追踪当前单击事件的速度

1
2
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);

 2. 当我们想知道当前的滑动速度时

1
2
3
velocityTracker.copmuteCurrentVelocity(1000); //计算一秒之内的变化情况
int xVelocity = (int) velocityTracker.getXVelocity(); //一秒之内X坐标的变化情况,从左向右为正
int yVelocity = (int) velocityTracker.getYVelocity(); //一秒之内Y坐标的变化情况,从上向下为正

 3. 不用时重置并回收内存

1
2
velocityTracker.clear();
velocityTracker.recycler();

手势GestureDetector

检测手势,用于辅助检测用户的单击、滑动、长按、双击等行为,使用方式如下:

 1. 创建GestureDetector对象并实现OnGestureListener和OnDoubleTapListener接口

1
GestureDetector mGestureDetector = new GestureDetector(this);

 2. 接管目标View的onTouchEvent方法,在View的onTouchEvent中添加:

1
2
boolean consume = mGestureDetector.onTouchEvent(event);
return consume;

方法介绍:

方法名 描述 所属接口
onDown 手指轻触屏幕的瞬间,由一个ACTION_DOWN触发 OnGestureListener
onShowPress 手指轻触屏幕,尚未拖动,强调没有松开或拖动的状态(个人理解在onDown之后) OnGestureListener
onSingleTapUp 单击,有可能是双击中的一次 OnGestureListener
onScroll 手指按下并拖动 OnGestureListener
onLongPress 长按 OnGestureListener
onFling 按下屏幕快速滑动后松开 OnGestureListener
onDoubleTap 双击,由两次单击组成,不能与onSingleTapConfirmed共存 OnDoubleTapListener
onSingleTapConfirmed 严格的单击行为,不可能是双击中的一次 OnDoubleTapListener
onDoubleTapEvent 双击,在双击期间,ACTION_UP、ACTION_MOVE、ACTION_DOWN都会触发此回调 OnDoubleTapListener

弹性滑动Scroller

scrollTo和scrollBy过程是瞬间完成的,某些情况下用户体验并不好,而利用Scroller可以实现弹性滑动,使用方法如下:

  • 在继承View的类中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Scroller mScroller = new Scroller(mContext);
//缓慢滑动到指定位置
private void smoothScrollTo(int destX, int destY) {
trueint scrollX = getScrollX();
trueint delta = destX - scrollX;
truemScroller.startScroll(scrollX, 0, delta, 0, 1000); //1s内缓慢滑动到destX
trueinvalidate();
}
@Override
public void computeScroll(){
trueif (mScroller.computeScrollOffset()) {
truetruescrollTo(mScroller.getCurrX(), mScroller.getCurrY());
truetruepostInvalidate();
true}
}
分享到 评论