View是Android中全部控件的基类,view自己能够是单控件也能够是由多控件组成的控件android
View的位置参数:api
‘ide
View自身提供的获取坐标的方法:函数
getTop():获取view自身的顶边到其父布局顶边的距离。布局
getLeft():获取view自身的左边到其父布局左边的距离。post
getRight():获取view自身的右边到其父布局左边的距离。性能
getBottom():获取view自身的底边到其父布局顶边的距离。动画
手指接触屏幕锁产生的事件,经常使用的以下:this
ACTION_DOWN——手指刚接触屏幕google
ACTION_MOVE——手指在屏幕上移动
ACTION_UP——手指从屏幕上松开的一瞬间
MotionEvent提供的方法:
getX() :获取点击事件距离控件左边的距离,即视图坐标。
getY() :获取点击事件距离控件顶边的距离,即视图坐标。
getRawX():获取点击事件距离整个屏幕左边的距离,即绝对坐标。
getRawY():获取点击事件距离整个屏幕顶边的距离,即绝对坐标。
根据方法注释理解这个touchSlop是一个滑动距离值的常量,也就是说当咱们手触摸在屏幕上滑动时,若是滑动距离没有超过touchSlop值的话 ,android系统自己是不会认为咱们在屏幕上作了手势滑动,所以只有当咱们在屏幕上的滑动距离超过touchSlop值时,android系统自己才会认为咱们作了滑动操做并去响应触摸事件,不过要注意的是不一样的设备,touchSlop的值多是不一样的,一切以上述的函数获取为准
VelocityTracker是个速度跟踪类,用于跟踪手指滑动的速度,包括x轴方向和y轴方向的速度。
使用过程:在view的onTouchEvent方法中追踪当前单击事件的速度
VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event);
当咱们想知道当前的滑动速度时,能够采用以下方式来获取当前的速度:
velocityTracker.computeCurrentVelocity(1000); int xVelocity = (int) velocityTracker.getXVelocity(); int yVelocity = (int) velocityTracker.getYVelocity();
若是不须要使用它时,须要调用clear方法来重置并回收内存:
velocityTracker.clear(); velocityTracker.recycle();
computeCurrentVelocity (int units),基于当前咱们所收集到的点计算当前的速率,当咱们肯定要得到速率信息的时候,在调用该方法,由于使用它须要消耗很大的性能。
参数:units 咱们想要指定的获得的速度单位,若是值为1,表明1毫秒运动了多少像素。若是值为1000,表明1秒内运动了多少像素。这个方法还有一个重载函数 computeCurrentVelocity (int units, float maxVelocity), 跟上面同样也就是多了一个参数。
参数:maxVelocity 该方法所能获得的最大速度,这个速度必须和你指定的units使用一样的单位,并且必须是整数.也就是,你指定一个速度的最大值,若是计算超过这个最大值,就使用这个最大值,不然,使用计算的的结果,
这个最大速度能够经过ViewConfiguration.get(context).getScaledMaximumFlingVelocity()方式获取。
getXVelocity()和getYVelocity() ,这两个很简单,得到横向和竖向的速率。前提是必定要先调用computeCurrentVelocity (int units)函数计算当前速度!
速度的计算公式,能够用下列公式来表示,因此说速度能够时负数:
速度 = (终点位置 - 起点位置) / 时间段
手势监听类,用于辅助检测用户的单击、滑动、长按、双击等行为
使用:先建立一个GestureDetector对象并实现OnGestureListener接口,根据须要还能够实现OnDoubleTapListener从而可以监听双击行为:
GestureDetector gestureDetector = new GestureDetector(this); //解决长按屏幕后没法拖动的现象 gestureDetector.setIsLongpressEnabled(false);
接着,接管目标View的onTouchEvent方法,在须要等待监听的View中的onTouchEvent方法中添加以下实现:
boolean consume = gestureDetector.onTouchEvent(event); return consume;
// 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发 public boolean onDown(MotionEvent arg0) { Log.i("MyGesture", "onDown"); Toast.makeText(this, "onDown", Toast.LENGTH_SHORT).show(); return true; } /* * 用户轻触触摸屏,还没有松开或拖动,由一个1个MotionEvent ACTION_DOWN触发 * 注意和onDown()的区别,强调的是没有松开或者拖动的状态 */ public void onShowPress(MotionEvent e) { Log.i("MyGesture", "onShowPress"); Toast.makeText(this, "onShowPress", Toast.LENGTH_SHORT).show(); } // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发 // 很是快的点击Touchup:onDown>onSingleTapUp>onSingleTapConfirmed // 稍微慢点的点击Touchup:onDown>onShowPress>onSingleTapUp>onSingleTapConfirmed public boolean onSingleTapUp(MotionEvent e) { Log.i("MyGesture", "onSingleTapUp"); Toast.makeText(this, "onSingleTapUp", Toast.LENGTH_SHORT).show(); return true; } // 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发 // 参数一:第一个MotionEvent // 参数二:最后一个MotionEvent // 参数三:velocityX X轴上的移动速度,像素/秒 // 参数四:velocityY Y轴上的移动速度,像素/秒 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i("MyGesture", "onFling"); Toast.makeText(this, "onFling", Toast.LENGTH_LONG).show(); return true; } // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发 // 滑屏:手指触动屏幕后,稍微滑动后当即松开onDown-->onScroll-->onScroll-->onScroll-->onFling // 拖动: onDown-->onScroll-->onScroll-->onFiling public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.i("MyGesture", "onScroll"); Toast.makeText(this, "onScroll", Toast.LENGTH_LONG).show(); return true; } // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发 //触发顺序:onDown->onShowPress->onLongPress public void onLongPress(MotionEvent e) { Log.i("MyGesture", "onLongPress"); Toast.makeText(this, "onLongPress", Toast.LENGTH_LONG).show(); }
// 单击时发出通知。 @Override public boolean onSingleTapConfirmed(MotionEvent e) { return false; } // 发生双击时通知。 @Override public boolean onDoubleTap(MotionEvent e) { return false; } //当发生双击手势中的事件(包括向下,向上和向上事件)时通知。 @Override public boolean onDoubleTapEvent(MotionEvent e) { return false; }
google官方api:
https://developer.android.com/reference/android/view/GestureDetector.OnDoubleTapListener
弹性滑动对象,用来实现View的弹性滑动,Scroller自己没法让view弹性滑动,它须要和view的computeScroll方法配合使用才能共同完成这个功能。
实现view滑动的三种方式:
scrollTo跟scrollBy其移动的本质都是View/ViewGroup中的内容,而且移动的过程都是瞬间完成的
scrollTo喝scrollBy都是View中的方法,不是Scroller中的方法,可是控制View的平滑移动与Scroller类密不可分。
scrollTo() : **指是的移动的绝对位置,若是位置没有变化,屡次调用则不会起做用。
scrollBy() : **其本质依然是调用的scrollTo(),指的的移动当前位置的相对距离(每次都是先将当前的位置和设置的距离相加之和调用scrollTo(),这样若是你屡次调用,你就会发现其每次都会移动一段距离,这是和scrollTo()的本质区别)
/** * Set the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the x position to scroll to * @param y the y position to scroll to */ public void scrollTo(int x, int y) { if (mScrollX != x || mScrollY != y) { int oldX = mScrollX; int oldY = mScrollY; mScrollX = x; mScrollY = y; invalidateParentCaches(); onScrollChanged(mScrollX, mScrollY, oldX, oldY); if (!awakenScrollBars()) { postInvalidateOnAnimation(); } } } /** * Move the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the amount of pixels to scroll by horizontally * @param y the amount of pixels to scroll by vertically */ public void scrollBy(int x, int y) { scrollTo(mScrollX + x, mScrollY + y); }
scrollBy实际上也是调用了scrollTo方法,它实现了基于当前位置的相对滑动,而scrollTo则实现了基于所传递参数的绝对滑动
view若是从左向右滑动,那么mScrollX为负值,不然为正值;若是从上往下滑动,那么mScrollY为负值,不然为正值
经过动画可让一个view进行平移,平移也能够说是一种滑动,使用动画来移动view,主要是操做view的translationX和translationY属性,既能够采用传统的view动画,也可使用属性动画
若是想给button向右移动,只须要将这个button的LayoutParams里的marginLeft参数的值增长100px便可
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams(); params.width += 100; params.leftMargin += 100; button.setLayoutParams(params);