View的基础知识

来源:互联网 发布:淘宝5元店铺红包怎么用 编辑:程序博客网 时间:2024/06/06 10:57

View的基础知识

View的位置参数

View的位置主要由它的四个顶点来决定:top,left,right,bottom

top:控件的左上角横坐标
left:控件的左上角纵坐标
right:控件的右下角横坐标
bottom:控件的右下角纵坐标

必须要注意的是:这些坐标都是相对于View的父容器而言的,因此它是一种相对坐标。

根据相对坐标得出View的长和宽:

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

View中的这四个参数对应mLeft,mTop,mRight,mBottom
并拥有对应的get/set方法。

从Android 3.0开始View中增加了x,y,translationX,translationY参数。其中x,y表示View左上角的坐标,translationX,translationY表示View左上角相对于父View的偏移量,这两个偏移量默认是0。
这四个参数多是相对于父容器的坐标,也都提供了get/set方法。这几个参数的换算关系如下:
x = left + translationX;
y = rigth +transltationY;

需要注意的是:View在平移的过程中,top和left表示的是原始左上角的位置信息,其值并不会发生变化,此时发生改变的是x,y,translationX,translationY这四个参数。

MotionEvent和TouchSlop

MotionEvent

ACTION_DOWN
ACTION_MOVE
ACTION_UP

点击屏幕后离开:
ACTION_DOWN -> ACTION_UP

点击屏幕滑动一会再松开:
ACTION_DOWN - > ACTION_MOVE … MOVE …. MOVE ->ACTION_UP

通过MotionEvent可以获得点击事件发生的x坐标和y坐标,View提供了两组方法,getX()和getY() / getRowX()和getRowY(),区别是:
getX()/getY()是相对于当前View左上角的x和y坐标。
getRowX()/getRowY()是相对于手机屏幕左上角的x和y坐标。

TouchSlop

TouchSlop是系统能够识别出来的被认为是滑动的最小距离,也就是如果手指在屏幕上滑动的距离如果小于该值,那么系统不认为这是滑动。TouchSlop是一个常量,和设备有关,不同设备上值可能不同。获取方法:

ViewConfigration().get(getContext).getScaledTouchSlop();

该值的意义是在处理滑动时可以用该值过滤,比如如果两次滑动事件的距离小于该值,那么就可以认为没有达到滑动的临界值,就可以不认为是滑动,这样做可以拥有更好的用户体验。

该值在源码中的位置:
frameworks/base/core/res/res/values/config.xml文件中,其中
view_viewConfigrationTouchSlop就是该值。

VelocityTracker,GestureDetctor,Scroller

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

VelocityTracker velocityTracker = VelocityTracker.obtin();velocityTracker.addMovement(event);

接着,当我们想要知道当前的滑动速度时,通过如下的方法获取当前速度:

velocityTracker.computeCurrentVelocity();int xVelocity = (int)velocityTracker.getXVelocity();int yVelocity = (int)velocityTracker.getYVelocity();

计算滑动速度有两点需要注意:
1. 在获取速度前必须要先计算速度,即在调用getXVelocity()和getYVelocity()前必须要先调用computeCurrentVelocity();
2. 这里的速度是指在一段时间内手指滑过的像素数,比如设置事件为1000ms,在1s内手指水平方向滑过的像素数是100,那么水平方向的速度就是100。
3. 注意速度可以为负数,当手指从右向左滑动时,速度就为负数。

速度的计算公式为:

速度 = (终点位置-起点位置) / 时间

根据上面的公式在加上Android系统的坐标系可知,手指逆着坐标系的正方向滑动,所获取的速度就是负值,computeCurrentVelocity()表示的是一个时间单元或者时间间隔,单位是毫秒(ms),计算速度时得到的速度就是在这个时间间隔内手指在水平或者垂直方向内手指滑动的像素数。

注意:在不需要它的时候需要一下方法重置并回收内存:

velocityTracker.clear();velocityTracker.recyle();

GestureDetector

手势检测,用于检测用户的点击/滑动/长按/双击等行为。使用方法:

首先创建GestureDetector对象并实现onGestureListener接口,根据需要还可以实现onDoubleTapListener接口,从而能够监听双击的行为。

GestureDetector mGestureDetector = new GestureDetector(this);// 解决长按屏幕后无法拖动的现象mGestureDetector.setIsLongpressEnabled(false);

接着,接管目标View的onTouchEvent()方法,在待监听目标View的onTouchEvent()中添加如下的代码:

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

做完了上面两步,就可以有选择的实现onGestureListencer和onDoubleTapListener接口了,两个接口中的方法介绍如下所示:

方法名 描述 所属接口 onDown 手指轻轻触摸屏幕的一瞬间,由一个ACTION_DOWN触发 onGestureListencer onShowPress 手指轻轻触摸屏幕,尚未松开或拖动,由一个ACTION_DOWN触发,注意与onDown的区别,它强调的是手指尚未松开或拖动的状态 onGestureListencer onSingleTapUp 手指(轻轻触摸屏幕后)松开,伴随着一个MotionEvent ACTION_UP而触发,这是单击行为 onGestureListencer onScroll 手指按下屏幕并拖动,由一个ACTION_DOWN和多个ACTION_MOVE触发,这是拖动行为 onGestureListencer onLongPress 手指长久的按着屏幕不放,即长按 onGestureListencer onFling 用户按下触摸屏,快速滑动后松开,由一个ACTION_DOWN/多个ACTION_MOVE和一个ACTION_UP触发,这是快速滑动行为 onGestureListencer onDoubleTap 双击,由两次连续的单击组成,它不可能和onSingelTapConfirmed共存 onDoubleTapListener onSingelTapConfirmed 严格的单击行为 ×注意与onSingleTapUp的区别,如果触发了onSingelTapConfirmed,那么后面不可能再紧跟着另外一个单击行为,即这只可能是单击,不可能是双击中的一次单击 onDoubleTapListener onDoubleTapEvennt 表示发生了双击行为,再次期间ACTION_DOWN/ACTION_MOVE和ACTION_UP都会触发此回调 onDoubleTapListener

以上的方法中在日常开发中最常用的是:onSingleTapUp(单机)/onFling(快速滑动)/onScroll(拖动)/onLongPress(长按)/onDoubleTap(双击)

Scroller

弹性滑动对象,用于实现View的弹性滑动。当使用View的scrollTo和scrollBy方法来进行滑动时,其过程是瞬间完成的,这个没有过度效果的滑动用户体验不好。这个时候可以使用Scroller来实现有过渡效果的滑动,其过程不是瞬间完成的,而是在一定时间间隔内完成的。Scoller本身并无法使得View弹性滑动,它需要和View的computeSroll方法配合使用才能共同完成这个功能。使用Scroller的典型代码是固定的:

Scroller mScroller = new Scroller(mContext);// 缓慢滑动到指定位置private smoothScrollTo(int destX,int destY){   int scrollX = getScrollX();   int delta = destX - scrollX;   // 1000ms内滑向destX,效果就是慢慢滑动   mScroller.startScroll(scrollX,0,delta,0,1000);   invalidate();}@Overritepublic void computeScroll(){if(mScroller.computeScrollOffset()){    scrollTo(mScroller.getCurrX,mScroller.getCurrY);    postInvalidate();  }}

View的滑动

原创粉丝点击