您的位置:首页 > 其它

View的事件体系---V3.1 View基础知识

2016-04-12 22:54 375 查看
什么是View

View是Android中所有控件的基类,像我们平时用到的Button TextView都继承自View。
同时,像RelativeLayout LinearLayout等ViewGroup也同样继承于View,ViewGroup内部同时可以包含多个子View,并且这个子View同样还可以是ViewGroup。继承关系如下




View是一种界面层的控件的一种抽象。

View的位置参数

View的位置主要由它的四个顶点决定的,分别对应View的四个属性:top left bottom right。其中top是左上角纵坐标,left是左上角横坐标,right是右上角横坐标,bottom是右下角纵坐标。
这些坐标都是相对于View的父容器来说的,因此是一种相对坐标。示例如下:




根据图可以得出View的宽高和坐标之间的关系

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

这四个点的坐标可以通过getLeft() getRight() getBottom() getTop()四个方法来获取到
从Android3.0开始,View增加了几个额外的参数:x y translationX translationY,其中x y分别对应View左上角的坐标,translationX translationY是View左上角相对于父容器的偏移量,这几个参数也是相对于父容器的坐标,并且translationX translationY的默认值为0,和View的四个基本的位置参数一样,View也为他们提供了get/set方法,对应关系如下:

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

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

MotionEvent和TouchSlop

MotionEvent

在手指触摸屏幕所产生的一些列事件中,典型的事件类型有以下三种:

MotionEvent.ACTION_DOWN---手指刚触摸屏幕,按下操作
MotionEvent.ACTION_UP---手指从屏幕上松开的一瞬间
MotionEvent.ACTION_MOVE---手指在屏幕上滑动

通过motionEvent对象我们可以得到点击事件发生的x y坐标

getX() getY()返回的是相对于当前View左上角的x和y坐标
getRawX() getRawY()返回的是相对于手机屏幕左上角的x和y坐标

TouchSlop

TouchSlop是系统所能识别的被认为是滑动的最小距离,也就是说当手指在屏幕上进行滑动时,如果滑动距离小于这个数,那么系统不会认为这是一次滑动。
这是一个常量,和设备有关,也就是说在不同的设备上,这个值可能是不一样的,获取这个值的方式为:ViewConfiguration.get(context).getScaledTouchSlop()
可以帮助我们有效的处理用户滑动事件,这个值可以在frameworks/base/core/res/res/values/config.xml中找到

VelocityTracker GestureDetector和Scroller

VelocityTracker

速度追踪,用于追踪手指在滑动过程中的速度,包括水平和垂直速度。
使用比较简单,如下:VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event);
当我们想要知道当前速度的时候,可以采用如下方式:

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

需要注意两点

在获取当前速度之前必须先要计算速度
这里的速度指手指一段时间内滑过的像素数,比如将时间设置为1000ms,取到的就是在1S内手指滑过得像素数,加入水平方向滑过100像素,那么这个水平速度就是100.

当手指从左往右滑,速度为正值,从右向左滑为负值,上下同理。计算公式为:速度 = (终点位置 - 起点位置)/时间段
当不需要使用的时候,需要调用clear方法来重置并回收内存。

velocityTracker.clear();
velocityTracker.recycle();

GestureDetector

手势检测,用于辅助检测用户的单击 双击 长按 滑动等行为,使用也挺简单的。
首先创建一个GestureDetector对象,并实现onGestureListener接口,根据需要,还可以实现onDoubleTapListener从而监听双击行为。如下

GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
/**
* 手指轻轻触摸屏幕的一瞬间,1个Action_down触发
* @param e
* @return
*/
@Override
public boolean onDown(MotionEvent e) {
return false;
}

/**
* 手指轻轻触摸屏幕,尚未松开或拖动,由1个Action_down触发
* 与onDown相比,强调的是没有松开或者拖动的状态
* @param e
*/
@Override
public void onShowPress(MotionEvent e) {

}

/**
* 手指松开,伴随1个action_up
* @param e
* @return
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}

/**
* 手指按下屏幕并拖动,1个ACTION_DOWN N个ACTION_MOVE
* @param e1
* @param e2
* @param distanceX
* @param distanceY
* @return
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}

/**
* 长按屏幕
* @param e
*/
@Override
public void onLongPress(MotionEvent e) {

}

/**
* 手指按下触摸屏,快速滑动后松开,强调的是快速滑动行为
* @param e1
* @param e2
* @param velocityX
* @param velocityY
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});

GestureDetector.OnDoubleTapListener onDoubleTapListener = new GestureDetector.OnDoubleTapListener() {

/**
* 严格的单击行为
* 和onSingleTapUp的区别为,如果触发了onSingleTapConfirmed,那么后面不可能在紧跟着另外一个单击行为,
* 这只可能是单击,而不是双击中的一次单击
* @param e
* @return
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}

/**
* 双击 两次连续的单击构成,不可能和onSingleTapConfirmed并存
* @param e
* @return
*/
@Override
public boolean onDoubleTap(MotionEvent e) {
return false;
}

/**
* 表示发生了双击行为,在双击的期间,ACTION_DOWN ACTION_MOVE ACTION_UP都会触发此回调
* @param e
* @return
*/
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
};


在实际开发中,可以不使用GestureDetector,完全可以自己在View的onTouchEvent中实现自己的需求。建议,如果只是监听滑动行为,自己在onTouchEvent中实现,如果有双击行为的话,通过gesturedector来实现。

Scroller

弹性滑动对象,用于实现View的弹性滑动
scrolleTo/scrollBy方法实现滑动,是瞬间完成的,没有过度效果
使用Scroller对象来实现由过渡效果的滑动,需要和View的compuScroll方法配合使用完成,模板代码如下:

private void init(Context context){
mScroller = new Scroller(context);
}

private void smoothScrollTo(int destX,int destY){
int scrollX = getScrollX();
int scrollY = getScrollY();
mScroller.startScroll(scrollX,scrollY,destX,destY);
invalidate();
}

@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: