View

什么是View

        View是Android中全部控件的基类,view自己能够是单控件也能够是由多控件组成的控件android

 

View的位置参数:api

ide

View自身提供的获取坐标的方法:函数

getTop():获取view自身的顶边到其父布局顶边的距离。布局

getLeft():获取view自身的左边到其父布局左边的距离。post

getRight():获取view自身的右边到其父布局左边的距离。性能

getBottom():获取view自身的底边到其父布局顶边的距离。动画

 

MotionEvent

手指接触屏幕锁产生的事件,经常使用的以下:this

ACTION_DOWN——手指刚接触屏幕google

ACTION_MOVE——手指在屏幕上移动

ACTION_UP——手指从屏幕上松开的一瞬间

 

MotionEvent提供的方法:

getX() :获取点击事件距离控件左边的距离,即视图坐标。

getY() :获取点击事件距离控件顶边的距离,即视图坐标。

getRawX():获取点击事件距离整个屏幕左边的距离,即绝对坐标。

getRawY():获取点击事件距离整个屏幕顶边的距离,即绝对坐标。

 

 

TouchSlop

        根据方法注释理解这个touchSlop是一个滑动距离值的常量,也就是说当咱们手触摸在屏幕上滑动时,若是滑动距离没有超过touchSlop值的话 ,android系统自己是不会认为咱们在屏幕上作了手势滑动,所以只有当咱们在屏幕上的滑动距离超过touchSlop值时,android系统自己才会认为咱们作了滑动操做并去响应触摸事件,不过要注意的是不一样的设备,touchSlop的值多是不一样的,一切以上述的函数获取为准

 

VelocityTracker

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

        手势监听类,用于辅助检测用户的单击、滑动、长按、双击等行为

      使用:先建立一个GestureDetector对象并实现OnGestureListener接口,根据须要还能够实现OnDoubleTapListener从而可以监听双击行为:

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

        接着,接管目标View的onTouchEvent方法,在须要等待监听的View中的onTouchEvent方法中添加以下实现:

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

 

OnGestureListener中的接口:

// 用户轻触触摸屏,由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();
}

 

GestureDetector.OnDoubleTapListener中的接口:

// 单击时发出通知。
@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

 

Scroller

        弹性滑动对象,用来实现View的弹性滑动,Scroller自己没法让view弹性滑动,它须要和view的computeScroll方法配合使用才能共同完成这个功能。

 

 

 

 

View的滑动

实现view滑动的三种方式:

  1. 经过view自己提供的scrollTo/scrollBy方式来实现
  2. 经过动画给view施加平移效果来实现
  3. 经过改变view的LayoutParams使用view从新布局从而实现滑动

 

使用ScrollTo/ScrollBy

        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);

 

三种滑动方式的对比:

  • scrollTo/scrollBy:操做简单,适合对View内容的滑动;
  • 动画:错作简单,主要适用于没有交互的View和实现复杂的动画效果;
  • 改变布局参数:操做稍微复杂,适用于有交互的View
相关文章
相关标签/搜索