使用Scroller实现滚动

上一篇博客提到了使用scrollTo,scrollBy来实现滑动。那既然提到scrollBy,scrollTo,那就简单来说下Scroller类。
两者十分相似,有着千丝万缕的联系。那他们又有什么区别?分别的使用场景是什么呢?
Scroller可以现实带动画的平滑效果,而scrollTo,scrollBy则是瞬间完成的。控件随着手指的移动而移动,放手回到初始位置,这个简单的效果,可以用scrollby和Scroller类一起完成,第一阶段控件随着手移动用scrollby实现,因为他需要即时反馈的效果,而放手后回到原始位置可以用Scroller比较恰当,不会太突兀。代码如下:

public class ScrollWithScrollerView extends View{

    private int mLastX;
    private int mLastY;
    private Scroller mScroller;

    public ScrollWithScrollerView(Context context) {
        this(context, null);
    }

    public ScrollWithScrollerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollWithScrollerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int)event.getX();
        int y = (int)event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                break;

            case MotionEvent.ACTION_MOVE:
                int dx = x - mLastX;
                int dy = y - mLastY;
                ((View)getParent()).scrollBy(-dx, -dy);
                break;

            case MotionEvent.ACTION_UP:
                View parent = (ViewGroup)getParent();
                mScroller.startScroll(parent.getScrollX(),parent.getScrollY(),-parent.getScrollX(),-parent.getScrollY(),1500);
                invalidate();
                break;
        }

        return true;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()){
            ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            invalidate();
        }
    }
}

在使用Scroller类的时候核心是要重写computeScroll()。因为系统在绘制View的时候会在ondraw方法中调用该方法。这个方法实际上就是使用scrollTo方法,再结合scroller对象,帮助获取当前的移动的滚动值,通过不断的瞬间移动一段微小的距离来现实整体上一点平滑的移动效果,一般情况下,重写computeScroll()可以使用一下模板

@Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()){
            ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            invalidate();
        }
    }

computeScrollOffset方法是来判断是否完成整个滑动,返回false表示完成整个滑动过程。
上面唯一要注意的是,不要忘了invalidate(),因为computeScroll方法不会自动调用,要通过invalidate()-draw()-computeScroll()来间接调用computeScroll方法。

开始滑动的两个方法

startScroll(int startX, int startY, int dx, int dy, int duration) 

startScroll(int startX, int startY, int dx, int dy)

这两个方法的本质是一样的。也非常好理解参数的含义,需要注意的是调用完此方法,不要忘了invalidate(),因为需要间接调用computeScroll方法开始模拟滑动。

Scroller类非常强大,Android中许多厉害的空间内部用的都是Scroller,如ListView等,这篇文章只是简单的介绍了一下它的用法。下一篇博客简单介绍下ViewDragHelper

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值