参考资料:http://blog.csdn.net/vipzjyno1/article/details/24592591 非常感谢这个兄弟!

在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现。。

先来看一下demo的效果:  下载地址

学习Scroller这个类之前你需要学习一下下面的知识:

  1、Scroller的2个方法scrollTo()和scrollBy()不了解的点这里 scrollTo()和scrollBy()的区别 知道的跳过这一步

  2、屏幕中的触摸事件分发机制(这一块在涉及到触摸的任何情况下都十分重要)现在自行百度吧,我还没有整理好关于事件分发的资料,后续我会整理一篇。

[学习总结]4、Android的ViewGroup中事件的传递机制(一)

下面看一下这个类的概述:

This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) 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, use 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:

跟踪变化的x / y坐标的位置,通过computeScrollOffset()方法监听返回的布尔值来指示滚动动作是否完成。如果返回为false,说明滚动已经结束。返回true,它意味着操作仍在进行中。您可以使用

int currX = mScroller.getCurrX();    //滚动的X滚动距离

int currY = mScroller.getCurrY();     //滚动的y滚动距离

这个方法来找到当前的x和y坐标的偏移量。

在看一下构造函数

Public Constructors
 
Scroller(Context context)
Create a Scroller with the default duration and interpolator.
 
Scroller(Context context, Interpolator interpolator)
Create a Scroller with the specified interpolator.
 
Scroller(Context context, Interpolator interpolator, boolean flywheel)
Create a Scroller with the specified interpolator.

Interpolator interpolator 表示的是动画插入器,你可以设定相应的效果给它。

下面是所有的插入器

AccelerateDecelerateInterpolator     动画效果:开始和结束都是缓慢的,通过中间时候加速

AccelerateInterpolator,      动画效果:开始缓慢,之后加速

AnticipateInterpolator,       动画效果:开始后退,然后前进

AnticipateOvershootInterpolator,   动画效果:开始后退,之后前进并超过终点位置,最终退回到终点

BounceInterpolator,        动画效果:慢慢反弹到,弹性衰减到结束

CycleInterpolator,          动画效果:重复循环动画,速度变化遵循正弦定律

DecelerateInterpolator,        动画效果:刚开始快速,之后减速

LinearInterpolator,         动画效果:不断的变化

OvershootInterpolator         动画效果:像前超越最终点然后回来

可以通过初始化构造方法Scroller(Context context, Interpolator interpolator)给它相应的动画效果。

Interpolator interpolator = new BounceInterpolator();

在看一下他的公用方法:

blic Methods
void
abortAnimation()    停止动画,滚到最终的x,y位置中止动画
boolean
computeScrollOffset()   当你想要知道新的位置时候,调用该方法。返回true:动画没结束
void
extendDuration(int extend)   延长滚动动画的时间。extend表示延迟时间(单位为毫秒)
void
fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
在fling(快速滑动,触摸屏幕后快意移动松开)的手势基础上开始滚动,滚动距离取决于fling的初速度。
final void
forceFinished(boolean finished)   强制终止滚动。
float
getCurrVelocity()   返回当前的速度
final int
getCurrX()    返回当前滚动的X方向的偏移量(距离原点X轴方向)
final int
getCurrY()   返回当前滚动的Y方向的偏移量(距离原点Y轴方向)
final int
getDuration()   返回滚动事件的持续时间(毫秒)
final int
getFinalX()  返回滚动结束的X方向的偏移量(注:只针对fling 手势有效)(距离原点X轴方向)
final int
getFinalY()   返回滚动结束的Y方向的偏移量(注:只针对fling 手势有效)(距离原点Y轴方向)
final int
getStartX()   返回滚动起始点的X方向偏移量(距离原点X轴方向)
final int
getStartY()  返回滚动起始点的Y方向偏移量.(距离原点Y轴方向)
final boolean
isFinished()   返回scroller滚动是否结束,true:滚动结束    false:还在滚动
void
setFinalX(int newX)  设置scroller的终止时X方向偏移量
void
setFinalY(int newY)   设置scroller的终止时Y方向偏移量
final void
setFriction(float friction)
The amount of friction applied to flings.
void
startScroll(int startX, int startY, int dx, int dy)
提供起始点和滚动距离,调用该方法进行滚动。(此处默认时间为250ms)
void
startScroll(int startX, int startY, int dx, int dy, int duration)
提供起始点和滚动距离以及滚动时间,调用该方法进行滚动。
int
timePassed()  返回自滚动开始经过的时间(毫秒)

源码

下面看看以上方法的源码实现:

知识点1:computeScrollOffset()方法

 1  /**
2 * Call this when you want to know the new location. If it returns true,
3 * the animation is not yet finished. loc will be altered to provide the
4 * new location.
5 */
6 public boolean computeScrollOffset() {
7 if (mFinished) {
8 return false; //已经完成了本次动画,直接返回为false
9 }
10 int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
11
12 if (timePassed < mDuration) {
13 switch (mMode) {
14 case SCROLL_MODE:
15 float x = timePassed * mDurationReciprocal;
16
17 if (mInterpolator == null)
18 x = viscousFluid(x);
19 else
20 x = mInterpolator.getInterpolation(x);
21
22 mCurrX = mStartX + Math.round(x * mDeltaX);
23 mCurrY = mStartY + Math.round(x * mDeltaY);
24 break;
25 case FLING_MODE:
26 final float t = (float) timePassed / mDuration;
27 final int index = (int) (NB_SAMPLES * t);
28 float distanceCoef = 1.f;
29 float velocityCoef = 0.f;
30 if (index < NB_SAMPLES) {
31 final float t_inf = (float) index / NB_SAMPLES;
32 final float t_sup = (float) (index + 1) / NB_SAMPLES;
33 final float d_inf = SPLINE_POSITION[index];
34 final float d_sup = SPLINE_POSITION[index + 1];
35 velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
36 distanceCoef = d_inf + (t - t_inf) * velocityCoef;
37 }
38 mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f;
39
40 mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
41 // Pin to mMinX <= mCurrX <= mMaxX
42 mCurrX = Math.min(mCurrX, mMaxX);
43 mCurrX = Math.max(mCurrX, mMinX);
44
45 mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
46 // Pin to mMinY <= mCurrY <= mMaxY
47 mCurrY = Math.min(mCurrY, mMaxY);
48 mCurrY = Math.max(mCurrY, mMinY);
49 if (mCurrX == mFinalX && mCurrY == mFinalY) {
50 mFinished = true;
51 }
52 break;
53 }
54 }
55 else {
56 mCurrX = mFinalX;
57 mCurrY = mFinalY;
58 mFinished = true;
59 }
60 return true;
61 }

调用该方法判断滚动是否还在继续,mFinished属性判断是否滚动完成,如果滚动完成了,mFinished = true,computeScrollOffset() 返回false。

知识点2:computeScroll()方法

1     /**
2 * Called by a parent to request that a child update its values for mScrollX
3 * and mScrollY if necessary. This will typically be done if the child is
4 * animating a scroll using a {@link android.widget.Scroller Scroller}
5 * object.
6 */由父视图调用用来请求子视图根据偏移值 mScrollX,mScrollY重新绘制
7 public void computeScroll() {
8 }

知道了computeScrollOffset()这个判断是否滚动的方法,那我们必须要有监听滑屏控制,并且重绘,在Android框架中的VIEW类中就提供了computeScroll()这个方法去控制该流程。在绘制View时,会在draw()过程调用该方法。因此, 再配合使用Scroller实例,我们就可以获得当前应该的偏移坐标,手动使View/ViewGroup偏移至该处。

注:在使用Scroller这个类实现偏移控制,一般自定义View/ViewGroup都需要重载该方法 。

具体实现:

 1 @Override
2 public void computeScroll() {
3 if (mScroller.computeScrollOffset()) {
4 scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
5 // 更新界面
6 postInvalidate();
7 isMoving = true;
8 } else {
9 isMoving = false;
10 }
11 super.computeScroll();
12 }

知识点3:startScroll()方法

 1  /**
2 * Start scrolling by providing a starting point and the distance to travel.
3 *
4 * @param startX //水平方向滚动的偏移值,以像素为单位。正值表明滚动将向左滚动
5 * @param startY //垂直方向滚动的偏移值,以像素为单位。正值表明滚动将向上滚动
6 * @param dx //水平方向滑动的距离,正值会使滚动向左滚动
7 * @param dy //垂直方向滑动的距离,正值会使滚动向上滚动
8 * @param duration //滚动持续时间
9 */
10 public void startScroll(int startX, int startY, int dx, int dy, int duration) {
11 mMode = SCROLL_MODE;
12 mFinished = false;
13 mDuration = duration;
14 mStartTime = AnimationUtils.currentAnimationTimeMillis();
15 mStartX = startX;
16 mStartY = startY;
17 mFinalX = startX + dx;
18 mFinalY = startY + dy;
19 mDeltaX = dx;
20 mDeltaY = dy;
21 mDurationReciprocal = 1.0f / (float) mDuration;
22 }

该方法以提供的起始点和将要滑动的距离开始滚动,我们可以使用该方法达到自动滚动的效果。在滚动中,如果符合什么条件,可以调用该方法让它滚动到相对应的地方。

着重点:

在界面滚动中,你必须搞清楚和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类大体的使用和介绍已经完毕,结合上面介绍的这些看一下上面的demo我相信你的收获一定很大的。这东西虽然都不是我写的,但是都是我读懂之后才放上来的,1是为了给大家分享一下,2就是我自己的笔记。

[学习总结]3、Android---Scroller类(左右滑动效果常用的类)的更多相关文章

  1. Android三种左右滑动效果 手势识别

    Android三种左右滑动效果 手势识别(转)   手势识别 1.onCreate中添加GestureDetector mGestureDetector; //监听手势事件 mGestureDetec ...

  2. Android快速开发系列 10个常用工具类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基本都会有一大批的辅 ...

  3. 【转】 Android快速开发系列 10个常用工具类 -- 不错

    原文网址:http://blog.csdn.net/lmj623565791/article/details/38965311 转载请标明出处:http://blog.csdn.net/lmj6235 ...

  4. Android三种左右滑动效果 手势识别(转)

    本示例演示在Android中实现带渐显按钮的左右滑动效果. 关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问: http://www.cnblogs.com/hanyonglu/archi ...

  5. Android 常用工具类之SPUtil,可以修改默认sp文件的路径

    参考: 1. 利用Java反射机制改变SharedPreferences存储路径    Singleton1900 2. Android快速开发系列 10个常用工具类 Hongyang import ...

  6. java面试复习重点:类的管理及常用工具,教你抓住面试的重点!

    java复习: 类的管理及常用工具类 包 写在程序文件的第一行 一个Java 源文件中只能声明一个包, 且声明语句只能作为源文件的第一条指令 导入类能导入非public类,但是不能用因为在其他包缺省的 ...

  7. android Scroller类的理解

    Scroller 一个特例: **点击Button后可能View没有移动,要关闭硬件加速,这段代码中int detalX = (int) (event.getX() - downX)要更正. demo ...

  8. Android中ViewPager实现滑动条及与Fragment结合的实例教程

    ViewPager类主要被用来实现可滑动的视图功能,这里我们就来共同学习Android中ViewPager实现滑动条及与Fragment结合的实例教程,需要的朋友可以参考下 自主实现滑动指示条先上一个 ...

  9. 详解实现Android中实现View滑动的几种方式

    注: 本文提到的所有三种滑动方式的完整demo:ScrollDemo 1. 关于View我们需要知道的 (1)什么是View? Android中的View类是所有UI控件的基类(Base class) ...

随机推荐

  1. ESXi 6.7 的https服务挂掉处理方法 503 Service Unavailable

    首先进入EXSi开启SSH(ESXi的主机控制台,非web控制台,是安装esxi的控制台) 然后 /etc/init.d/hostd status 显示已停止, 使用 /etc/init.d/host ...

  2. WSL2学习和使用汇集

    接触WSL2过程中整理沉淀的一些知识点,大纲如下,内容比较多,详细内容参考https://www.yuque.com/wushifengcn/kb/mbg1b5 欢迎感兴趣者补充和提出问题,共同学习. ...

  3. Canvas 放烟花合集 -- 用粉丝头像做成烟花绽放🧨

    "我对着烟花许愿,希望你永远在我身边" "凑不够满天星辰那就去看看烟花吧,人间烟火气,最抚凡人心" 小tips:喜欢的可以关注博主私信代码噢~ 也可以看看前面两 ...

  4. k8s入坑之路(8)kube-proxy详解

    kube-proxy 每台机器上都运行一个 kube-proxy 服务,它监听 API server 中 service 和 endpoint 的变化情况,并通过 iptables 等来为服务配置负载 ...

  5. 大爽Python入门教程 总目录

    作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 大爽Python入门公开课教案 本篇博客为公开课教案目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节, ...

  6. scrapy获取当当网中数据

    yield 1. 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代 2. yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yiel ...

  7. python3排序 sorted(key=lambda)--实现对字典按value值排序

    使用python对列表(list)进行排序,说简单也简单,说复杂也复杂,我一开始学的时候也搞不懂在说什么,只能搜索一些英文文章看看讲解,现在积累了一些经验,写在这里跟大家分享, 1.sorted函数首 ...

  8. VC练习一

    1 #include<windows.h> 2 #include<stdio.h> 3 LRESULT CALLBACK WinSunProc(HWND hwnd,UINT u ...

  9. [atAGC022D]Shopping

    称0到$L$的方向为左,同时为了方便,可以假设$0<t_{i}\le 2L$ 当我们确定是进入店中的方向,根据这个店的位置以及购物时间,不难确定出来时火车经过0或$L$的次数,由于$0<t ...

  10. Python学习手册——第二部分 类型和运算(1)之字符串

    Python全景 1.程序由模块构成. 2.模块包含语句. 3.语句包含表达式. 4.表达式建立并处理对象. 在python中数据是以对象的形式出现的!!! 为什么使用内置类型 内置对象使程序更容易编 ...