Scroller类深入浅出

来源:互联网 发布:python caffe 命令行 编辑:程序博客网 时间:2024/05/17 22:14

1 序言

在安卓中,一些应用总是会使用滑动来让自己得到改善,例如植物大战僵尸2中选择植物,就有用到滑动.这些效果本质上来说就是移动一个View,改变其当前所在的位置.所以,如果要实现View的滑动,就必须监听用户的触摸事件,并监听传入的坐标,来实现滑动.


2 安卓坐标系

在安卓中,屏幕左上角为Android坐标系的原点,这个点以右边边和下边为正方向,在触碰事件中,getRawX和getRawY是获得Android坐标系的坐标.


3 视图坐标系

视图坐标系描述了子视图在父视图中的位置,和安卓坐标系相同,他也是以右边和下边为正方向,在触碰事件中,getX和getY获得的是视图坐标系的XY坐标.我们也可以调用View的方法,来获取坐标.

视图左侧位置  view.getLeft()视图右侧位置 view.getRight()视图顶部位置 view.getTop();视图底部位置 view.getBottom();视图宽度 view.getWidth();视图高度 view.getHeight()




4 触碰事件---MotionEvent

   public static final int ACTION_DOWN             = 0;单点触摸动作    public static final int ACTION_UP               = 1;单点触摸离开动作    public static final int ACTION_MOVE             = 2;触摸点移动动作    public static final int ACTION_CANCEL           = 3;触摸动作取消     public static final int ACTION_OUTSIDE          = 4;触摸动作超出边界    public static final int ACTION_POINTER_DOWN     = 5;多点触摸动作    public static final int ACTION_POINTER_UP       = 6;多点离开动作


MotionEvent封装了用户的触碰操作,以上是一些常用的常量.

5 获取MotionEvent

一般情况下,我们是通过重写TouchEvent(MotionEvent event)方法来获得MotionEvent类.在方法中,我们只需要调用event.getAction就可以获得触碰事件的类型,如下面的例子所示.

@Override  public boolean onTouchEvent(MotionEvent event) {  Log.i("test",event.getAction()+"");}

6 实现滑动


前面说了,本质上,滑动就是改变View的坐标,我们了解了坐标系和触碰事件之后,我们就可以调用API来实现滑动了,在一个View中,我们可以通过scrollTo和scrollBy来实现改变View位置,scrollTo的作用是移动到一个具体的位置,而scrollBy表示移动的增量(在原有的基础上移动的距离).但是需要注意,如果我们想让View本身移动而不是他的content的话,我们需要在利用父类(getParent())来调用这两个方法.我们先做个试验,看一下,

@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {case MotionEvent.ACTION_DOWN:((View)getParent()).scrollTo(10, 10);break;default:break;}return super.onTouchEvent(event);}

我们调用ScrollTo方法,让他往X坐标正方向移动10个单位,但是发现是往反边移动的,所以我们认为当我们设置scrollTo的参数为正数时,他是往反方向移动的,而负数是往正方向移动的,现在我们看看Scroller类,没错,也就是我们的这次的猪脚登场了,他和前面的两个方法有着很大的联系,但是前面两个方法的移动都是瞬间完成的,移动过程非常不平滑.而Scroller类可以帮我们实现平滑移动.一般情况下,使用Scroller,需要三个步骤.

  1. 初始化Scroller,通过构造函数来创建一个Scroller对象
  2. 重写computeScroll()方法,实现平滑移动
  3. startScroll开启模拟移动


我们先来重写computeScroll()方法,他是Scroll类的核心,如下所示:

@Overridepublic void computeScroll() {if(mScroller.computeScrollOffset()){scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();}

首先我们分析一下这个方法,这个方法没办法主动调用 ,它是通过ondraw方法来调用的.所以我们想使用它,就要调用ondraw()方法,我们调用刷新invalidate()函数,间接完成了调用,,Scroll对象的computeScrolloffset方法,它代表着一个bool变量,当我们滑动操作完成时,他就是false的,这样我们就理清思路了下面我们调用startScroll方法来开启滑动

.

private void smooth(int dx,int dy){mScroller.startScroll(getScrollX(), 0, dx-getScrollX(), dy,5000);invalidate();}
在这个startScroll方法中的五个参数依次代表:

  1. 开始滑动的X坐标
  2. 开始滑动的Y坐标
  3. 目标的X坐标
  4. 目标的Y坐标
  5. 全部移动完成所需要的时间

至此,我们算是非常熟悉和了解Scroller了

0 0