public class MyTextView extends TextView {
Scroller mScroller;
public MyTextView(Context context) {
this(context,null);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
}
public void smoothScrollTo(int desx,int desy) {
int currX = getScrollX();
int dx = desx - currX;
mScroller.startScroll(currX,0,dx,0,1000);
invalidate();
}
//经测试,该方法运行在主线程
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();//因为是主线程,这里调用invalidate也可以
}
}
}
在代码中我们这样调用
//负号代表向右移动
myTextView.smoothScrollTo(-300,-300);
在解释Scroller的试用前,我们先来解释一个问题:关于thi和super的问题
http://www.cnblogs.com/iamzhoug37/p/4372934.html
接下来我们讲解Scroller的用法及原理。
首先说一下,
我们创建了一个Scroller对象,然后调用了getScroller方法获取view中内容的当前位置,具体来说是是View的左边缘和View的内容之间的距离,
然后计算需要偏移的距离dx,
然后调用Scroller的startScroll方法,我们看看
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只是保存了我们传入的几个参数,那么我们如何让view开始滑动呢,就是接下来的invalidate方法,
invalidate会导致view重绘,调用draw方法,在draw方法里面会调用computeScroll方法,在View中,computeScroll是一个空的实现,我们在自定义View中实现这个方法,然后通过Scroller获取当前的位置,不断重绘,View的每一次重绘都会导致View进行小幅度的滑动,而多次的小幅度滑动就组成了弹性滑动,这就是Scroller的工作机制。