您的位置:首页 > 移动开发 > Android开发

《View的事件体系》(一)View基础知识

2017-03-09 16:04 253 查看
   虽然说View不是Android四大组件,但他的作用和重要性并不次于四大组件。那到底什么才是View?View在Android中是所有控件的基类,不管简单的Button还是复杂的ListView,他们共同的基类都是View。另外要提到的一点是ViewGroup同样继承了View,翻译过来大概就是控件组,实际也是这样,ViewGroup内部包含了一组View,他的子View同样可以是ViewGroup。既然ViewGroup继承了View,所以View既可以是单个控件也可以是由多个控件组成的一组控件,通过这种结构就形成了View树。举个例子,Button是一个View,那LinearLayout不仅是一个View还是一个ViewGroup。有了更深入的学习之后就可以定义自定义View,比如继承自View或者ViewGroup的控件。

   先介绍一些View的基础知识,便于以后更深入的学习。View有很多基础概念,比较主要的有View的位置参数、MotionEvent、TouchSlop、VelocityTracker、GestureDetector和Scroll对象。下面会逐一介绍。

(1)View的位置参数

   View的位置主要由View的四个属性决定,分别是top、left、right和bottom。其中前两者对应左上角的纵坐标和横坐标,后两者对应右下角的横坐标和纵坐标。强调一点,这四个坐标是相对于他的父容器而言的,并不是在屏幕的绝对坐标。下面是View和父容器坐标的关系图:

         


   解释一下,在Android中原点在屏幕的左上角,向右和向下分别是X轴和Y轴的正方向。好像大部分显示系统都是用这个标准定义坐标系的。图中ViewGroup是View的父容器。从而View的宽高很容易的减法就计算出来了。但是在Android3.0之后,View增加了四个参数:
x , y, translationX和tranlationY。这个时候注意了,实际开发中可能需要View有平移的功能,此时top和left存储的是View未平移时原始左上角坐标,在平移的过程中View的左上角相对于父容器将会产生偏移值,这两个方向上的偏移值就存储在translationX和tranlationY。x和y是平移后View左上角相对父容器的坐标值。那么很显然:

x  = left + tranlationX;

y  = top+tranlationY;

   所以平移后发生改变的是Android3.0添加的四个参数,前面说的四个参数不变。 

(2)MotionEvent和TouchSlop

MotionEvent对应了手指触摸屏幕后所产生的一系列事件,典型的有以下几种:

·ACTION-DOWN:手指刚接触屏幕

·ACTION-MOVE:手指在屏幕上移动

·ACTION-UP:手指从屏幕上松开的一瞬间

通过MotionEvent对象我们可以获得点击事件发生的坐标值:

·getX/getY:返回相对于当前View左上角的x和y;

·getRawX/getRawY:返回相对于手机屏幕左上角的x和y。



   TouchSlop是系统所能识别出的被认为是滑动的最小距离,如果手指在平面上滑动的起点和终点的距离小于这个值则不认为是滑动。这是一个和系统有关的常量,不同设备的这个值可能是不同的。所以用户在屏幕上滑动一会再松开可能触发一系列MotionEvent:DOWN->MOVE->……MOVE->UP。在我们处理滑动的时候,可以通过设定这个常量的做一些滑动的过滤,比如小于几倍的TouchSlop就不认为是滑动,提高用户体验。

 

(3)VelocityTracker

   这个参数代表速度追踪,用于追踪手指在界面的滑动速度,包括水平和数直两个方向的速度。使用很简单,首先在View的onTouchEvent方法追踪当前点击事件的速度:

VelocityTracker velocityTracker = VelocityTracker.obtain();

velocityTracker.addMovement();

接着通过下面的方式获取速度:

velocityTracker.computeCurrentVelocity(1000);

int xVelocity =(int) velocityTracker.getXVelocity();

int yVelocity =(int) velocityTracker.getYVelocity();

   代码中可以看出需要先调用computeCurrentVelocity计算出速度,方法参数的默认单位是ms,这里使用1000指1s内手指在纵横两个方向划过的像素作为速度。注意这里的速度是有方向的,向屏幕负方向滑动速度就是负值,向正方向滑动速度就是正值。最后不需要他的时候记得用clear方法重置并回收内存:

velocityTracker.clear();

velocityTracker.recycle();

   可见这个参数掌握起来并不复杂。

 

(4) GestureDetector

   GestureDetector代表手势识别,用于辅助检测用户的单击、滑动、长按和双击等行为,他的使用也不复杂。参考下面的过程:

   首先创建他的对象:

GestureDetector gestureDetector = new GestureDetector();

gestureDetector.setIsLongpressEnabled(false);//解决长按屏幕没有响应的现象

   接着接管View的onTouchEvent方法,在监听View的onTouchEvent方法中添加:

boolean consume =gestureDetector.onTouchEvent();

return consume;

   下面就可以看需要实现onGestureListener和onDoubleTapListener等GestureDetector的其他接口,不再详述。实际开发中也没必要一定用GestureDetector,在View的onTouchEvent方法完全可以实现监听。不过如果仅仅监听滑动,在View的onTouchEvent方法实现即可;如果监听双击,用GestureDetector比较好。

 

(5)Scroll

  Scroll指弹性滑动对象,用于实现View的弹性滑动。开发的时候使用ScrollTo和ScrollBy完成的过程是瞬间的,没有过渡效果,所以体验并不好。这个时候就可以用Scroll实现有过渡效果的滑动。但是仅仅它本身并不能完成,还需要和View的computeScroll相互配合才行。下面是一个典型代码:

Scroller scroller =new Scroller(context);

private voidsmoothScrollTo(int x,int y){

   int scrollX = getScrollX();

   int delta = x – scrollX;

   //1000秒内滑向x,慢慢移动

   scroller.startScroll(scrollX,0,delate,0,1000);

   invalidate();

}

@Override

public voidcomputeScroll(){

   if(scroller.computeScrollOffset()){

     scrollTo(scroller.getCurrX(),scroller.getCurrY());

      postInvalidate();

}

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android View