android Scroller的用法总结

在android开发中有多种方式实现View的滑动,常见的有以下几种:

 1.不断的修改View的LayoutParams;
 2.通过动画对View实现位移的效果;
 3.调用View的ScrollTo(),ScrllBy().

这里要说的是第三种方式

首先看看ScrollTo(),ScrllBy()的用法: 
scrollTo(int x, int y):
scrollTo( )表示View相对于其初始位置滚动某段距离。

  • 当x为正值时,表示View向左滚动了x距离
  • 当x为负值时,表示View向右移动了x距离
  • 当y为正值时,表示View向上滚动了y距离
  • 当y为负值时,表示View向下移动了y距离
    scrollBy(intx, int y):
    看过源码就知道
public void scrollBy(int x, int y) {
   scrollTo(mScrollX + x, mScrollY + y);
}

它是在原来mScrollX,mScrollY的基础上接着滚动的
注意:这里并不是View自身在滚动,而是View里的内容在滚动。
通过上面两个方法确实可以实现View的滚动,但我们要想让View像我们常见的ViewPager那样平滑的滚动,只用这两方法是做不到的,因为它们产生的滚动是不连贯的,闪烁的,所以系统也为我们提供了Scroller这个类来实现View的平滑滚动。
Scroller从源码中我们可以看到如何使用的:

  * <pre> private Scroller mScroller = new Scroller(context);
  * ...
  * public void zoomIn() {
  *     // Revert any animation currently in progress
  *     mScroller.forceFinished(true);
  *     // Start scrolling by providing a starting point and
  *     // the distance to travel
  *     mScroller.startScroll(0, 0, 100, 0);
  *     // Invalidate to request a redraw
  *     invalidate();
  * }</pre>
  *
  * <p>To track the changing positions of the x/y coordinates, use
  * {@link #computeScrollOffset}. The method returns a boolean to indicate
  * whether the scroller is finished. If it isn't, it means that a fling or
  * programmatic pan operation is still in progress. You can use this method to
  * find the current offsets of the x and y coordinates, for example:</p>
  *
  * <pre>if (mScroller.computeScrollOffset()) {
  *     // Get current x and y positions
  *     int currX = mScroller.getCurrX();
  *     int currY = mScroller.getCurrY();
  *    ...
  * }</pre>

根据上面文档的描述可把Scroller的使用概括为以下五个主要步骤:

  1. 初始化Scroller
  2. 调用startScroll()开始滚动
  3. 执行invalidate()刷新界面
  4. 重写View的computeScroll()并在其内部实现与滚动相关的业务逻辑
  5. 再次执行invalidate()刷新界面
    mScroller.startScroll(int startX,int startY,int dx,int dy)
    startX:表示View X坐标滚动的开始位置;
    startY:表示View Y坐标滚动的开始位置 
    dx:表示View 从X坐标的开始位置需要滚动的距离(这里dx的正负是和ScrllTo() 的x一样的)
    dy:表示View 从Y坐标开始位置需要滚动的距离(dy的正负和scrllTo的 y 一样的)
/**
   * Start scrolling by providing a starting point, the distance to travel,
   * and the duration of the scroll.
   * 
   * @param startX Starting horizontal scroll offset in pixels. Positive
   *        numbers will scroll the content to the left.
   * @param startY Starting vertical scroll offset in pixels. Positive numbers
   *        will scroll the content up.
   * @param dx Horizontal distance to travel. Positive numbers will scroll the
   *        content to the left.
   * @param dy Vertical distance to travel. Positive numbers will scroll the
   *        content up.
   * @param duration Duration of the scroll in milliseconds.
   */
  public void startScroll(int startX, int startY, int dx, int dy, int duration) {
      mMode = SCROLL_MODE;
      mFinished = false;
      mDuration = duration;
      mStartTime = AnimationUtils.currentAnimationTimeMillis();
      mStartX = startX;
      mStartY = startY;
      mFinalX = startX + dx;
      mFinalY = startY + dy;
      mDeltaX = dx;
      mDeltaY = dy;
      mDurationReciprocal = 1.0f / (float) mDuration;
  }

通过源码可以看到,当调用startScroll()时,内部并没有做什么滚动的操作,只是做了赋值的操作,所以当调用了这段代码之后,我们需要调用invalidate()方法来让View重绘从而调用View里computeScroll(方法,在View源码里computeScroll()方法是个 空实现,所以我们可以在这个方法里面做滚动的逻辑。

比如这样:

public void computeScroll(){
   if (mScroller.computeScrollOffset()) {
      scrollTo(0, mScroller.getCurrY());
      postInvalidate();
  }
    super.computeScroll();
}

另外在computeScroll()方法里,我们一般用mScroller.compuScrollOffset()来判断View的滚动是否在继续,返回true表示还在继续,false表示结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值