View的事件体系(一)——View的基础知识以及View的滑动

一.View的基础知识

1.View是一种界面层的控件的一种抽象,它代表了一个控件。

2.View的位置参数

View的位置主要由它的四个顶点来确定,分别对应于View的四个属性:top,left,right,bottom。这些坐标都是相对于View的父容器来说的,因此它是一种相对坐标。3.0之后增加的几个参数为:x,y,translationX,translationY。其中x,y是View左上角的坐标,translationX,translationY是View左上角相对于父容器的偏移量。

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

3.MotionEvent和TouchStop

   (1)MotionEvent

    在手指接触屏幕后产生的一系列事件中,典型的事件类型有如下几种:

  • ACTION_DOWN ——手指刚接触屏幕
  • ACTION_MOVE——手指在屏幕上移动
  • ACTION_UP——手指从屏幕上松开的一瞬间
   正常情况下,一次手指触摸屏幕的行为会触发一系列点击事件,可能出现如下两种情况:
  • 点击屏幕后离开松手,事件序列为:DOWN->UP
  • 点击屏幕滑动一会再松开,事件序列为:DOWN->MOVE->...->MOVE->UP
   (2)TouchSlop
    TouchSlop是系统所能识别出的被认为是滑动的最小距离。这是一个常量,和设备有关,在不同设备上,这个值可能不同。通常可以通过如下方式获取该常量:ViewConfiguration.get(getContext()).getScaledTouchSlop()
4.VelocityTracker,GestureDetector,Scroller
   (1)VelocityTracker
   速度追踪,用于追踪手指在滑动过程中的速度,包括水平和竖直方向上的速度。首先,在View的onTouchEvent方法中追踪当前单击事件的速度:
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
   接着,当我们想知道当前的滑动速度时,可以采用如下方法获得:
velocityTracker.computeurrentVelocity(100);//100表示时间间隔为100 ms
int x=(int) velocityTracker.getXVelovity();
int y=(int) velocityTracker.getYVelovity();
最后,当不需要使用它的时候,需要调用clear方法来重置并回收内存:
velocityTracker.clear();
velocityTracker.recycle();
   (2)GestureDetector
    手势检测,用于辅助检测用户的单击,滑动,长按,双击等行为。首先,需要创建一个GestureDetector对象并实现OnGestureListener接口,根据需要还可以实现OnDoubleTapListener,从而能够监听双击行为:
GestureDetector mGestureDetector =new GestureDetector(this);
//解决长按屏幕无法拖动的现象
mGestureDetector.setIsLongPressEnable(false);
   接着,接管目标View的onTouchEvent方法,在待监听View的onTouchEvent方法中,添加如下实现:
Boolean consume=mGestureDetector.onTouchEvent(event);
return consume;
   (3)Scroller
    弹性滑动对象,用于实现View的弹性滑动。
Scroller scroller =new Scroller(mContext);
Private void smoothScrollTo(int destX,int destY) {
  int scrollX=getScrollX();
  int delta = destX - scrollX;
  mSroller.startScroll(scrollX,0delta,0,1000);
  invalidate();
}
@Override
Public void computeScroll(){
  if(mSroller.computeScrollOffset()) {
    scrollTo(mScroller.getCurrX().mScroller.getCurrY());
    postInvalidate();
  }
}

二.View的滑动
下面介绍三种方式,实现View的滑动:
  • 第一种,是通过View本身提供的scrollTo/scrollBy方法来实现滑动的
  • 第二种,是通过动画给View施加平移效果来实现滑动的
  • 第三种,是通过改变View的LayoutParams使得View重新布局,从而实现滑动
1.使用scrollTo/scrollBy
   在滑动过程中,没ScrollX的值总是等于View左边缘和View内容左边缘在水平方向上的距离;mScrollY的值总是等于View上边缘和View内容上边缘在竖直方向上的距离。View的边缘是指View的位置,由四个顶点组成。scrollTo/scrollBy只能改变View内容的位置,而不能改变View在布局中的位置。
2.使用动画
   使用动画移动View,主要是操作View的translationX和translationY属性,既可以采用传统的View动画,也可以采用属性动画。采用属性动画则更为简单,下面采用属性动画,将一个View在100ms内从原始位置向右平移100像素:
ObjectAnimator.ofFloat(targetView,”translationX”,0,100).setDuration(100).start();
上面介绍的这种方法,并不能真正改变View的位置,还会带来一个严重的问题。比如通过一个View动画将Button向右移动100px,但是当你点击新位置时,无法触动onClick事件,而单击原始位置,却可以触发该事件。
在这里简单的提供一种解决思路:我们可以在新位置预先创建一个和目标Button一模一样的Button,当目标Button完成平移后,就把目标Button隐藏,同时把预先创建的Button显示出来,通过这种间接的方式,就可以解决上述问题了。
3.改变布局参数
   改变布局参数,即改变LayoutParams。例如将一个Button向右平移100px:
MarginLayoutParams params = (MarginLayoutParams )mButton1.getLayoutParams();
Params.width +=100;
params.leftMargin +=100;
mButton1.requestLayout();
//或者 mButton1.setLayoutParams(params);

三.弹性滑动
1.使用Scroller
   Scroller本身并不能实现View的滑动,它需要配合View的computeScroll方法才能完成弹性滑动的效果。它不断让View重绘,每一次重绘距滑动起始时间会有一个时间间隔,通过这个时间间隔Scroller就可以得出View当前的滑动位置,知道了滑动位置,就可以通过scrollTo方法来完成View的滑动。
2.通过动画
   实现方法一:
ObjectAnimator.ofFloat(targetView,”translationX”,0,100).setDuration(100).start();
   实现方法二:
Final int startX=0;
Final int deltax=100;
valueAnimator animator = ValueAnimator.ofInt(0,1).setDuration(1000);
animator.addUpdateListener(new AnimatorUpdateListener(){
  @Override
  public void onAnimatorUpdate(ValueAnimator animator){
    Float fraction=animator.getAnimatedFraction();
    mButton1.scrollTo(startX+(int)(deltaX*fraction),0)
  }
});
animator.start();

3.使用延时策略
   它的核心思想是通过发送一系列延时消息从而达到一种渐进式的延时效果,具体来说可以使用Handler或View的postDelayed方法,也可以使用线程sleep的方法。


以上就是View的一些基础知识了,过几天学习一下View的事件分发机制,再写博客进行整理……


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值