Android 滑动界面实现---Scroller类别 从源代码和开发文档了解(让你的移动布局)
2015-07-03 14:40
639 查看
在android学习,行动互动是软件的重要组成部分,其中Scroller是提供了拖动效果的类,在网上。比方说一些Launcher实现滑屏都能够通过这个类去实现。。
样例相关博文:Android
仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源代码
在广泛使用的側边滑动导航开源库 --SlidingLayer事实上就是使用到了Scroller类进行的实现,下载地址:GITHUB
。以下要讲的不是这个库,而是这个库的实现过程中使用到的---Scroller类。懂了之后你看库的源代码就知道,原来它是这样实现的。
Scroller类使用过程中,懂得下面机制可能会对开发更有帮助:
1.视图的VIEW的自己定义以及其在屏幕中布局。
2.scrollTo()和scrollBy()方法的作用差别
能够点击此处了解:android
布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
3.屏幕中的触摸事件分发机制(这一块在涉及到触摸的不论什么情况下都十分重要)
首先看看发开文档里面说了些什么:
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
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坐标的偏移量。
Interpolator interpolator 表示的是动画插入器,你能够设定对应的效果给它。
Interpolator
implements TimeInterpolator
AccelerateDecelerateInterpolator
动画效果:開始和结束都是缓慢的。通过中间时候加速
AccelerateInterpolator,
动画效果:開始缓慢。之后加速
AnticipateInterpolator,
动画效果:開始后退,然后前进
AnticipateOvershootInterpolator,
动画效果:開始后退,之后前进并超过终点位置,终于退回到终点
BounceInterpolator,
动画效果:慢慢反弹到,弹性衰减到结束
CycleInterpolator,
动画效果:反复循环动画,速度变化遵循正弦定律
DecelerateInterpolator,
动画效果:刚開始高速。之后减速
LinearInterpolator,
动画效果:不断的变化
OvershootInterpolator
动画效果:像前超越终于点然后回来
能够通过初始化构造方法Scroller(Context context, Interpolator interpolator)给它对应的动画效果。
Interpolator interpolator = new BounceInterpolator();
调用该方法推断滚动是否还在继续。mFinished属性推断是否滚动完毕,假设滚动完毕了,mFinished
= true,computeScrollOffset() 返回false。
知道了computeScrollOffset()这个推断是否滚动的方法,那我们必需要有监听滑屏控制,而且重绘,在Android框架中的VIEW类中就提供了computeScroll()这种方法去控制该流程。在绘制View时,会在draw()过程调用该方法。
因此。 再配合使用Scroller实例。我们就能够获得当前应该的偏移坐标,手动使View/ViewGroup偏移至该处。
注:在使用Scroller这个类实现偏移控制,一般自己定义View/ViewGroup都须要重载该方法
。
详细实现:
该方法以提供的起始点和将要滑动的距离開始滚动。我们能够使用该方法达到自己主动滚动的效果。在滚动中,假设符合什么条件。能够调用该方法让它滚动到相相应的地方。
布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
须要注意的是。移动的时候向左移动为负。向下移为负。示意图例如以下:
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类的应用) 附 2个DEMO及源代码
在广泛使用的側边滑动导航开源库 --SlidingLayer事实上就是使用到了Scroller类进行的实现,下载地址:GITHUB
。以下要讲的不是这个库,而是这个库的实现过程中使用到的---Scroller类。懂了之后你看库的源代码就知道,原来它是这样实现的。
Scroller类使用过程中,懂得下面机制可能会对开发更有帮助:
1.视图的VIEW的自己定义以及其在屏幕中布局。
2.scrollTo()和scrollBy()方法的作用差别
能够点击此处了解:android
布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
3.屏幕中的触摸事件分发机制(这一块在涉及到触摸的不论什么情况下都十分重要)
首先看看发开文档里面说了些什么:
android发开文档
开发文档參考链接:http://developer.android.com/reference/android/widget/Scroller.htmlScroller
一.结构关系
extends Object二.概述
Class Overview
This class encapsulates scrolling. You can use scrollers (Scrolleror
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
implements TimeInterpolator
android.view.animation.Interpolator |
动画效果:開始和结束都是缓慢的。通过中间时候加速
AccelerateInterpolator,
动画效果:開始缓慢。之后加速
AnticipateInterpolator,
动画效果:開始后退,然后前进
AnticipateOvershootInterpolator,
动画效果:開始后退,之后前进并超过终点位置,终于退回到终点
BounceInterpolator,
动画效果:慢慢反弹到,弹性衰减到结束
CycleInterpolator,
动画效果:反复循环动画,速度变化遵循正弦定律
DecelerateInterpolator,
动画效果:刚開始高速。之后减速
LinearInterpolator,
动画效果:不断的变化
OvershootInterpolator
动画效果:像前超越终于点然后回来
能够通过初始化构造方法Scroller(Context context, Interpolator interpolator)给它对应的动画效果。
Interpolator interpolator = new BounceInterpolator();
四.公共方法
Public 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()方法
/** * 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软键盘现实和隐藏的监听
- Android QQ登录验证的小例子
- android 5.2
- Android入门(5)——多状态按钮ToggleButton、多选按钮CheckBox、RadioGroup与RadioButtont按钮
- Android的消息机制
- Android Studio使用OpenCV的配置方法
- android工程里,配置文件的实现。
- Android RGB颜色对照表
- Android WebService
- android之AlertDialog 点击其他区域自动消失
- android之AlertDialog 点击其他区域自动消失
- android之AlertDialog 点击其他区域自动消失
- android之AlertDialog 点击其他区域自动消失
- Android Home and back
- 我的Android Studio 优化之路
- Android下常见的内存泄露
- Android 大约Dialog弹出窗口
- Android原型界面设计工具
- Android Studio使用OpenCV的配置方法
- android gradle task dependence