Class Overview
This class encapsulates scrolling. You can use scrollers (Scroller
orOverScroller
)
to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don't automatically apply those positions to your view. It's your responsibility to get and
apply new coordinates at a rate that will make the scrolling animation look smooth.
这个类封装了滚动操作,你可以根据你的手势对界面进行更加平滑的滚动操作。
To track the changing positions of the x/y coordinates, usecomputeScrollOffset()
.
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:
跟踪变化的x / y坐标的位置,通过computeScrollOffset()方法监听返回的布尔值来指示滚动动作是否完成。如果返回为false,说明滚动已经结束。返回true,它意味着操作仍在进行中。您可以使用
intcurrX=mScroller.getCurrX();//滚动的X滚动距离
intcurrY=mScroller.getCurrY();
//滚动的y滚动距离
这个方法来找到当前的x和y坐标的偏移量。
三.构造函数
Public Constructors
|
Create a Scroller with the default duration and interpolator.
|
|
Create a Scroller with the specified interpolator.
|
|
Create a Scroller with the specified interpolator.
|
Interpolatorinterpolator 表示的是动画插入器,你可以设定相应的效果给它。
Interpolator
android.view.animation.Interpolator
|
AccelerateDecelerateInterpolator
动画效果:开始和结束都是缓慢的,通过中间时候加速
AccelerateInterpolator,
动画效果:开始缓慢,之后加速
AnticipateInterpolator,
动画效果:开始后退,然后前进
AnticipateOvershootInterpolator,
动画效果:开始后退,之后前进并超过终点位置,最终退回到终点
BounceInterpolator,
动画效果:慢慢反弹到,弹性衰减到结束
CycleInterpolator,
动画效果:重复循环动画,速度变化遵循正弦定律
DecelerateInterpolator,
动画效果:刚开始快速,之后减速
LinearInterpolator,
动画效果:不断的变化
OvershootInterpolator
动画效果:像前超越最终点然后回来
可以通过初始化构造方法Scroller(Contextcontext,Interpolatorinterpolator)给它相应的动画效果。
Interpolator interpolator = new BounceInterpolator();
四.公共方法
Public Methods
void
|
|
boolean
|
|
void
|
|
void
|
fling(int
startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
在fling(快速滑动,触摸屏幕后快意移动松开)的手势基础上开始滚动,滚动距离取决于fling的初速度。
|
final void
|
|
float
|
|
final int
|
|
final int
|
|
final int
|
|
final int
|
getFinalX() 返回滚动结束的X方向的偏移量(注:只针对fling
手势有效)(距离原点X轴方向)
|
final int
|
getFinalY()
返回滚动结束的Y方向的偏移量(注:只针对fling 手势有效)(距离原点Y轴方向)
|
final int
|
|
final int
|
|
final boolean
|
isFinished() 返回scroller滚动是否结束,true:滚动结束
false:还在滚动
|
void
|
|
void
|
|
final void
|
The amount of friction applied to flings.
|
void
|
提供起始点和滚动距离,调用该方法进行滚动。(此处默认时间为250ms)
|
void
|
startScroll(int
startX, int startY, int dx, int dy, int duration)
提供起始点和滚动距离以及滚动时间,调用该方法进行滚动。
|
int
|
|
源码
下面看看以上方法的源码实现:
知识点1:computeScrollOffset()方法
/**
* Call this when you want to know the new location. If it returns true,
* the animation is not yet finished. loc will be altered to provide the
* new location.
*/
public boolean computeScrollOffset() {
if (mFinished) {
return false; //已经完成了本次动画,直接返回为false
}
int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
if (timePassed < mDuration) {
switch (mMode) {
case SCROLL_MODE:
float x = timePassed * mDurationReciprocal;
if (mInterpolator == null)
x = viscousFluid(x);
else
x = mInterpolator.getInterpolation(x);
mCurrX = mStartX + Math.round(x * mDeltaX);
mCurrY = mStartY + Math.round(x * mDeltaY);
break;
case FLING_MODE:
final float t = (float) timePassed / mDuration;
final int index = (int) (NB_SAMPLES * t);
float distanceCoef = 1.f;
float velocityCoef = 0.f;
if (index < NB_SAMPLES) {
final float t_inf = (float) index / NB_SAMPLES;
final float t_sup = (float) (index + 1) / NB_SAMPLES;
final float d_inf = SPLINE_POSITION[index];
final float d_sup = SPLINE_POSITION[index + 1];
velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
distanceCoef = d_inf + (t - t_inf) * velocityCoef;
}
mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f;
mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
// Pin to mMinX <= mCurrX <= mMaxX
mCurrX = Math.min(mCurrX, mMaxX);
mCurrX = Math.max(mCurrX, mMinX);
mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
// Pin to mMinY <= mCurrY <= mMaxY
mCurrY = Math.min(mCurrY, mMaxY);
mCurrY = Math.max(mCurrY, mMinY);
if (mCurrX == mFinalX && mCurrY == mFinalY) {
mFinished = true;
}
break;
}
}
else {
mCurrX = mFinalX;
mCurrY = mFinalY;
mFinished = true;
}
return true;
}
调用该方法判断滚动是否还在继续,mFinished属性判断是否滚动完成,如果滚动完成了,mFinished
= true,computeScrollOffset()返回false。
知识点2:computeScroll()方法
/**
* Called by a parent to request that a child update its values for mScrollX
* and mScrollY if necessary. This will typically be done if the child is
* animating a scroll using a {@link android.widget.Scroller Scroller}
* object.
*/由父视图调用用来请求子视图根据偏移值 mScrollX,mScrollY重新绘制
public void computeScroll() {
}
知道了computeScrollOffset()这个判断是否滚动的方法,那我们必须要有监听滑屏控制,并且重绘,在Android框架中的VIEW类中就提供了computeScroll()这个方法去控制该流程。在绘制View时,会在draw()过程调用该方法。因此,再配合使用Scroller实例,我们就可以获得当前应该的偏移坐标,手动使View/ViewGroup偏移至该处。
注:在使用Scroller这个类实现偏移控制,一般自定义View/ViewGroup都需要重载该方法
。
具体实现:
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
// 更新界面
postInvalidate();
isMoving = true;
} else {
isMoving = false;
}
super.computeScroll();
}
知识点3:startScroll()方法
/**
* Start scrolling by providing a starting point and the distance to travel.
*
* @param startX //水平方向滚动的偏移值,以像素为单位。正值表明滚动将向左滚动
* @param startY //垂直方向滚动的偏移值,以像素为单位。正值表明滚动将向上滚动
* @param dx //水平方向滑动的距离,正值会使滚动向左滚动
* @param dy //垂直方向滑动的距离,正值会使滚动向上滚动
* @param duration //滚动持续时间
*/
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;
}
该方法以提供的起始点和将要滑动的距离开始滚动,我们可以使用该方法达到自动滚动的效果。在滚动中,如果符合什么条件,可以调用该方法让它滚动到相对应的地方。
着重点:
在界面滚动中,你必须搞清楚和scrollTo和scrollBy之间的区别所在:android
布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
需要注意的是,移动的时候向左移动为负,向下移为负。示意图如下:
使用思路流程:
如果你使用Scroller,流程如下:
1.可以在自定义的布局中,按照需求初始化Scroller构造函数。
2.重写onInterceptTouchEvent(MotionEvent ev)方法,看看是否要拦截相关的点击时间。
3.重写onTouchEvent(MotionEvent event)方法,根据触摸屏上的动作使用computeScroll()以及scrollTo
和 scrollBy方法进行根据手指对布局进行滑动效果。
4.在触摸操作结束(MotionEvent.ACTION_UP)的时候,调用startScroll(int startX, int startY, int dx, int dy, int duration)方法,进行动画自动操作,来完成整个滚动流程。
对于Scroller类大体的使用和介绍已经完毕,之后会放上自己调用类实现的几个漂亮的效果。
相关推荐
Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,项目详情http://blog.csdn.net/xiaanming/article/details/17539199
博客《ListView滑动删除实现之四——Scroller类与listview缓慢滑动》对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/45317951
Android高级应用源码-Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用).zip
scroller类用法解析和scroller类实战案例类似ViewPager滑动功能
Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用).rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
Android Scroller实现View弹性滑动Demo
Android利用ViewPager实现类微信的左右滑动效果,详细代码注解解析setOnPageChangeListener各参数意义以及使用方法
Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
android scroller 滑动效果 简单demo
在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现。这个就是Scroller类学习的后的实践了,效果很棒哦。 你可以...
在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现。这个就是Scroller类学习的后的实践了,效果很棒哦。你可以去...
来自博客,http://blog.csdn.net/footballclub,欢迎留言交流
通过scroller学习,仿QQ ListView侧滑删除效果