一.View的基础知识
View的位置主要是由4个顶点来决定的,分别对应View的4个属性,left,top,right,bottom,其中top是左上角纵坐标,left是左上角横坐标,right是右上角横坐标,bottom是右上角纵坐标,需要注意的是,这些坐标是相对于View的父容器来说的,因此它是一种相对坐标
view的坐标和父容器的关系如下图所示
获取这4个成员变量的方法如下:
Left=getLeft();
Right=getRight();
Top=getTop();
Bottom=getBottom();
从android3.0开始,View增加了几个额外的参数:x,y,translationX和translationY,其中x,y是View左上角的坐标(View内容的坐标),而translationX和translationY是View左上角相对于父容器的偏移量, 这几个参数也是相对父容器的坐标,并且translationX和translationY的默认值为0
x=left+translationX;
y=top+translationY;
注意:View在平移的过程中,top和left表示的是原始左上角的位置信息,它的值并不会改变,发生改变的是x,y,translationX和translationY
getX()返回的是相对于当前的View左上角的X坐标
getRawX()返回的是相对于当前的 手机屏幕 左上角的X坐标
TouchSlop:是系统所能识别出的被认为是滑动最小距离,通过如下方式获得:
int touchSlop= ViewConfiguration.get(mContext).getScaledTouchSlop();
VelocityTracker:速度追踪,用于追踪手指在滑动过程中的平均速度,
使用:在view的onTouchEvent方法中添加如下代码
//设计模式中的享元模式
VelocityTracker mVelocityTracker=VelocityTracker.obtain();
mVelocityTracker.addMovement(event);
获取当前滑动的平均速度:
//先计算 时间单位;毫秒 计算在1000毫秒里面的平均速度
mVelocityTracker.computeCurrentVelocity(1000);
int yVelocity=(int) mVelocityTracker.getYVelocity();
int xVelocity=(int) mVelocityTracker.getXVelocity();
注意:
1,这里的速度是指:一段时间内手指划过的像素数
2,速度有可以有负数,正负表示方向
最后,当不要使用它的时候,要注意释放
mVelocityTracker.clear();;
mVelocityTracker.recycle();
GestureDetector:手势检测
使用:创建一个GestureDetector对象,并且实现OnGestureListener的接口,接着接管view的onTouch()方法,添加如下实现:
GestureDetector mGestureDetector= new GestureDetector(this);
return mGestureDetector.onTouchEvent(event);
Scroller:弹性滑动对象,用于实现View的弹性滑动,Scroller本身无法让View弹性滑动,它需要和View的computeScroll()配合使用才能完成
固定使用代码实现如下:
mScroller = new Scroller(context);
//平滑的缓慢滚动到指定的位置
public void smollSrcllTo(int desX,int dexY){
int scrollX=getScrollX();
int dx=desX-scrollX;
//X从scrollX在2000毫秒的时间里滚动dx的距离
mScroller.startScroll(scrollX,0,dx,0,2000);
//主线程中使用
invalidate();
}
//此方法父类是一个空实现,一定要重写
@Override
public void computeScroll() {
//offset:偏移量 返回true表示 动画还没有结束
if (mScroller.computeScrollOffset()) {
smollSrcllTo(mScroller.getCurrX(),mScroller.getCurrY());
//子线程中使用,如果是在主线程中用invalidate()
postInvalidate();
}
}
二.View的滚动 通过3种方式可以实现View的滑动:
第一种:View自身提供的scrllTo/ScrollBy来实现滑动(ScrollBy(()最后调用的也是scrllTo())
第二种;通过平移动画来实现
第三种,改变View的layoutParam使view重新布局从而实现滑动
说明:
1.通过scrllTo/ScrollBy来滚动的,滚动的是view的内容,view的4个点的坐标还是没有改变,(例如:listView的上下滚动,只是内容在动,listView控件本身的位置并没有发生改变)
2,传统的View动画,滚动的也是内容,但是属性动画滚动的是View控件本身
View的弹性滑动:
也是上面的3种方式实现:
第一种:View自身提供的scrllTo/ScrollBy来实现滑动
第二种;通过平移动画来实现
第三种:改变View的layoutParam使view重新布局从而实现滑动
(配合handle的postDelayed,或者线程的sleep)
根据时间流逝的百分比来滚动的思想要掌握;
ValueAnimator mValueAnimator= ValueAnimator.ofInt(0,1).setDuration(2000);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//动画更新的百分比
float fraction= animation.getAnimatedFraction();
MyTv.this.scrollTo(startX+(int)(dx*fraction),0);
}
});
ValueAnimator 本身不会作用于任何属性,它就是一个数值发生器,它可以产生你想要的任何数值,在属性动画中,产生的每一步动画效果,都是通过它来算出来的