View的事件体系之一基础知识

来源:互联网 发布:淘宝网不登录不能搜索 编辑:程序博客网 时间:2024/06/05 05:39

1.1View的概念

  View是Android中所有控件的基类,不管是复杂的LinearLayout还是ListView他们的共同基类都是View,所以说View是一种界面层的控件的一种抽象,它代表了一个控件。除了View还有ViewGroup,ViewGroup内部包含了很多View、也就是说,ViewGroup是一个是一个View组,并且在Android中,ViewGroup继承自View,这也就意味着View既可以是一个单独的控件,也可以是由多个控件组成的一组控件。通过这种关系构成了View的树结构。

1.2View的位置参数

  View的位置参数主要由它的四个顶点来决定,分别对应于View的四个属性:top,bottom,right,left。其中top是左上角纵坐标,left左上角横坐标,right是右下角横坐标,bottom是右下角纵坐标。需要注意这些坐标都是相当于它的父容器来说的,也就是说他是一种相对坐标。在大部分显示系统中包括Android,x轴和y轴的正方向分别是向右和向下。
view的位置坐标和父容器的关系

依据以上可以得知:View的宽高和坐标之间的关系是:

width=right-left;  height=bottom-top;

  从Android3.0开始,View增加了额外的参数:想,元,translationX和translationY,其中x和y是View左上角的坐标,而translationX和translationY是View左上角相对于父容器的偏移量。并且translationX和translationY默认值是0,view也给它们提供了get/set的方法,

x=left+translationX;  y=top+translationY;

注意:View在平移的过程中,top和left标识的是原始左上角的位置信息,其值并不会发生改变,此时发生改变的是x,y,translationX,和translationY。

1.3 MotionEvent 和 TouchSlop、VelocityTracker 、GestureDetector 和 Scroller

1.3.1 MotionEvent

  在手指接触屏幕后所产生的一系列事件中,典型的事件类型有几种:
- ACTION_DOWN:手指刚接触屏幕;
- ACTION_MOVE:手指在屏幕上移动;
- ACTION_UP:手指从屏幕上松开的一瞬间。

正常情况下一次手指触摸屏幕的行为会触发一系列点击事件,例如:
- 点击屏幕后松开,事件序列为DOWN–>UP;
- 点击屏幕滑动一会再松开,事件序列为DOWN–>MOVE–>….>MOVE–>UP;

通过MotionEvent对象我们可以得到点击事发生的x和y坐标。为此系统提供了两组方法:getX/getY和getRawX和getRawY。他们的区别其实很简单,getX/getY返回的是相对于当前View左上角的x和y的坐标。而getRawX和getRawY返回的是相对于手机屏幕左上角的x和y坐标。

1.3.2 TouchSlop

  TouchSlop是系统所能识别的被认为是最小滑动距离,换句话说,当手指在屏幕上滑动时,如果两次滑动之间的距离小于这个常量,那么系统就不认为你在进行一个滑动操作。这是一个常量,和设备有关,不同的设备上这个常量的值也许是不同的。获取方式为:ViewConfiguration.get(getContext()).getTouchSlop();

作用和意义:利用这个常量我们可以做一个过滤操作,比如当两次滑动事件的滑动距离小于这个值,我们就可以认为未达到滑动距离的临界值。

1.3.3 VelocityTracker

  速度追踪,用于追踪手指在滑动过程中的速度,包括水平和竖直方向的速度。它的使用过程很简单,首先,在View的onTouchEvent方法中追踪当前点击事件的速度:

VelocityTracker obtain = VelocityTracker.obtain();obtain.addMovement(event);

通过如下方式我们可以知道当前的速度,但是必须要注意:

 obtain.computeCurrentVelocity(1000);//计算当前的速率,1000ms为时间间隔 int xVelocity= (int) obtain.getXVelocity(); int yVelocity= (int) obtain.getYVelocity();
  • 获取速度之前必须要计算速度,即getXVelocity和getYVelocity这两个方法的前面必须要调用computeCurrentVelocity方法
  • 这里的速度是指一段时间内手指所划过的像素数,计算方式:速度=(终点位置-起点位置)/时间段。

最后,当不需要使用它的时候,需要调用clear方法来重置并回收内存。

obtain.clear();obtain.recycle();
1.3.4 GestureDetector

  GestureDetector手势检测,用于辅助检测用户的点击,滑动,长按,双击等行为。GestureDetector的使用过程:首先要创建一个GestureDetector的对象,并且实现OnGestureListener接口,根据需求我们还可以实现OnDoubleTapListener从而能够监听双击行为。其次,接管目标View的OnTouchEvent方法。
OnGestureListener接口和OnDoubleTapListener中的方法介绍:

     /**手指轻轻触摸屏幕的一瞬间,由一个ACTION_DOWN触发 **/    @Override    public boolean onDown(MotionEvent e) {        return false;    }   /**手指轻轻触摸屏幕,尚未松开或者拖动,由一个ACTION_DOWN触发 **/    @Override    public void onShowPress(MotionEvent e) {    }   /**手指轻轻触摸屏幕后松开,由一个ACTION_UP触发 ,这是一个单击行为**/    @Override    public boolean onSingleTapUp(MotionEvent e) {        return false;    }  /**手指轻轻触摸屏幕后拖动,由一个ACTION_DOWN,多个ACTION_MOVE触发 ,这是拖动行为**/    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        return false;    }  /**手指长时间按压屏幕不放,即长按事件**/    @Override    public void onLongPress(MotionEvent e) {    }  /**用户快速按下触摸屏,快速滑动后松开,由一个ACTION_DOWN,多个ACTION_MOVE,一个ACTION_UP触发,这是快速滑动行为**/    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {     return false;    }  /**属于双击监听OnDoubleTapListener接口,严格的单击行为,这只可能是单击而不可能是双击中的一个单击行为**/     @Override    public boolean onSingleTapConfirmed(MotionEvent e)    {     return false;    }    /**属于双击监听OnDoubleTapListener接口,双击,有两次连续的单击行为组成,不能和onSingleTapConfirmed共存**/    @Override    public boolean onDoubleTap(MotionEvent e)    {       return false;    }    /**属于双击监听OnDoubleTapListener接口,表示发生了双击行为,再双击的期间,ACTION_DOWN,ACTION_MOVE和ACTION_UP都会触发此回调/   @Override    public boolean onDoubleTapEvent(MotionEvent e)    {      return false;    }
1.3.5 Scroller

  弹性滑动对象,用于实现View的弹性滑动。我们知道,当使用View的scrollTo或者scrollBy方法来进行滑动的时候,其过程是瞬间完成的,没有一些过渡效果,而Scroller就是干这个的。它本身没法让View进行弹性滑动。他需要和View的computeScroll方法配合使用才能实现。