1.View的位置主要由四个顶点来决定,top,left,right,bottom,其中top是左上角总坐标,left是左上角横坐标,right是右下角横坐标,bottom是右下角纵坐标。这四个是相对父布局来说的。(可以说左上角的坐标是(left,top) 右下角的坐标是(right bottom)) 2.View的宽 width=right-left,height = bottom-top,left = getLeft() 其他属性类似。 3.android3.0以后额外增加了几个属性,x,y ,translationX,translationY其中x,y是Vie的左上角的坐标,而translationX,translationY是View左上角相对与父容器的偏移量,默认值是0,同时也有get/set方法。 x=left+translationX(初始left+偏移量0) y=right+translationY(初始right+偏移量0) left等属性是初始是原View的位置信息不会改变,发生改变时可通过修改偏移量translationX,translationY而对x,y进行修改。 4.MotionEvent手指在接触屏幕后产生的时间, ACTION_DOWN手指刚接触屏幕 ACTION_MOVE手指移动 ACTION_UP手指从屏幕离开的一瞬间 一边的触摸的情况有,点击屏幕DOWN-UP 移动DOWN-MOVE-MOVE-..-MOVE-UP 点击屏幕的时候会获取到x,y rawX,rawY 四个属性,x,y是相对于View左上角 rawX,rawY是相对于屏幕来说的。(这四个属性都可以通过get来获取 getX()) 5.TouchSlop使系统能识别的最小的滑动值可通过 ViewConfiguration.get(get(Context)).getScaledTouchSlop();来获取,进行一些自定义属性的判断 6.VelocityTracker 速度追踪,用与追踪手指在滑动过程中的数度包括水平和竖直方向的速度。
@Override public boolean onTouchEvent(MotionEvent event) { VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event); //获取当前的数度 velocityTracker.computeCurrentVelocity(1000);//获取速度之前必须先计算数度在getXVelocity();getYVelocity();方法前 int xVelocity = (int) velocityTracker.getXVelocity(); int yVelocity = (int) velocityTracker.getYVelocity(); //这里的数度是指在当时间间隔设置为1000ms时 在1s内,手指在水平方向从左向右划过100像素,那速度就是100 (此速度可以为负) //可以用公式 速度 = (终点位置-起始位置)/时间段 //最后当不需要使用时要调用clear方法来重置并回收 velocityTracker.clear(); velocityTracker.recycle(); return super.onTouchEvent(event); }7.GestureDetector 手势检测 用于辅助检测用户的单击,滑动,长按,双击等行为
首先要建立一个GestureDetector对象并实现OnGrestureListener接口,根据需求可实现OnDoubleTapListener实现双击行为
@Override public boolean onTouchEvent(MotionEvent event) { GestureDetector mGestureDetector = new GestureDetector(this); //解决长按屏幕后无法拖动的现象 mGestureDetector.setIsLongpressEnabled(false); // 接管View 的 onTouchEvent方法 boolean consume = mGestureDetector.onTouchEvent(event); return consume; } @Override public boolean onDown(MotionEvent e) { //手指轻松触摸屏幕的一瞬间 return false; } @Override public void onShowPress(MotionEvent e) { //手指轻松触摸屏幕尚未松开或尚未移动 } @Override public boolean onSingleTapUp(MotionEvent e) { //手指轻松触摸屏幕的一瞬间放开 单机行为 return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { //拖动行为 return false; } @Override public void onLongPress(MotionEvent e) { //长按行为 } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //手指按下后快速滑动后松开这是滑动行为 return false; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { //严格的单击行为 return false; } @Override public boolean onDoubleTap(MotionEvent e) { //双击 return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { //表示发生了双击行为,再双击的期间,ACTION_DOWN,ACTION_MOVE,ACTION_UP都会执行 return false; }在日常开发中 onSingleTapUp(单击)onFling(快速滑动)onScroll(拖动)onLongPress(长按)onDoubleTap(双击)比较常用
8.Scroller
private Scroller scroller = new Scroller(context); @Override public void computeScroll() { super.computeScroll(); if (scroller.computeScrollOffset()){ ScrollTo(scroller.getCurrX(),scroller.getCurrY()); postInvalidate(); } } private void smoothScrollTo(int destX, int destY){ int scrollX = getScrollX(); int delta = destX-scrollX; //1000ms内滑动destX,效果就是慢慢滑动 scroller.startScroll(scrollX,0,delta,0,1000); invalidate(); }9.View的滑动 (1)使用scrollTo/scrollBy
@Override public void scrollBy(int x, int y) { super.scrollBy(x, y); } 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(); } } }scrollTo是根据传递值的绝对滑动,scrollBy是相对滑动 但是不管怎么移动都不能改变View的位置只能改变View中内容的位置