Scroller的方法startScroll、fling、computeScrollOffset_scroller.startscroll-CSDN博客 (2024)

最近在使用开源库TableFixHeaders(https://github.com/InQBarna/TableFixHeaders),对于其中Scroller的用法不清楚,故看看这几个方法干了什么。

点与点之间的计算 + 触摸事件的分发。

1. startScroll

当startScroll执行过程中即在duration时间内,computeScrollOffset 方法会一直返回false,但当动画执行完成后会返回返加true.

如果不设置duration,默认DEFAULT_DURATION = 250.

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;}

看代码,这个方法就是把需要滚动的参数传进来。

2.fling

public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) { // Continue a scroll or fling in progress if (mFlywheel && !mFinished) { float oldVel = getCurrVelocity(); float dx = (float) (mFinalX - mStartX); float dy = (float) (mFinalY - mStartY); float hyp = (float) Math.hypot(dx, dy); float ndx = dx / hyp; float ndy = dy / hyp; float oldVelocityX = ndx * oldVel; float oldVelocityY = ndy * oldVel; if (Math.signum(velocityX) == Math.signum(oldVelocityX) && Math.signum(velocityY) == Math.signum(oldVelocityY)) { velocityX += oldVelocityX; velocityY += oldVelocityY; } } mMode = FLING_MODE; mFinished = false; float velocity = (float) Math.hypot(velocityX, velocityY); mVelocity = velocity; mDuration = getSplineFlingDuration(velocity); mStartTime = AnimationUtils.currentAnimationTimeMillis(); mStartX = startX; mStartY = startY; float coeffX = velocity == 0 ? 1.0f : velocityX / velocity; float coeffY = velocity == 0 ? 1.0f : velocityY / velocity; double totalDistance = getSplineFlingDistance(velocity); mDistance = (int) (totalDistance * Math.signum(velocity)); mMinX = minX; mMaxX = maxX; mMinY = minY; mMaxY = maxY; mFinalX = startX + (int) Math.round(totalDistance * coeffX); // Pin to mMinX <= mFinalX <= mMaxX mFinalX = Math.min(mFinalX, mMaxX); mFinalX = Math.max(mFinalX, mMinX); mFinalY = startY + (int) Math.round(totalDistance * coeffY); // Pin to mMinY <= mFinalY <= mMaxY mFinalY = Math.min(mFinalY, mMaxY); mFinalY = Math.max(mFinalY, mMinY);}

3. computeScrollOffset

功效:返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。

参考网址:http://www.cnblogs.com/tt_mc/p/3585390.html

public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal); 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;}

timePassed表示滚动进行到的时间,若滚动未结束,分SCROLL_MODE和FLING_MODE两种情况计算当前位置。

  • SCROLL_MODE下,
    时间最小单位mDurationReciprocal = 1.0f / (float) mDuration;
    通过差值器mInterpolator确定距离百分比,这里x和y方向使用同一差值器。
    mInterpolator = new ViscousFluidInterpolator(); 是Scroller的静态内部类,取值算法见getInterpolation()所调用的viscousFluid()。

    static class ViscousFluidInterpolator implements Interpolator {
    /* Controls the viscous fluid effect (how much of it). /
    private static final float VISCOUS_FLUID_SCALE = 8.0f;

    private static final float VISCOUS_FLUID_NORMALIZE;private static final float VISCOUS_FLUID_OFFSET;static { // must be set to 1.0 (used in viscousFluid()) VISCOUS_FLUID_NORMALIZE = 1.0f / viscousFluid(1.0f); // account for very small floating-point error VISCOUS_FLUID_OFFSET = 1.0f - VISCOUS_FLUID_NORMALIZE * viscousFluid(1.0f);}private static float viscousFluid(float x) { x *= VISCOUS_FLUID_SCALE; if (x < 1.0f) { x -= (1.0f - (float)Math.exp(-x)); } else { float start = 0.36787944117f; // 1/e == exp(-1) x = 1.0f - (float)Math.exp(1.0f - x); x = start + x * (1.0f - start); } return x;}@Overridepublic float getInterpolation(float input) { final float interpolated = VISCOUS_FLUID_NORMALIZE * viscousFluid(input); if (interpolated > 0) { return interpolated + VISCOUS_FLUID_OFFSET; } return interpolated;}

    }

  • FLING_MODE下,
    x和y还是同比例变化,这里设定了采样率NB_SAMPLES = 100;(??)
    index和index+1的含义?
    速度因子,velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
    距离因子,distanceCoef = d_inf + (t - t_inf) * velocityCoef;

4. invalidate() 与 postInvalidate()

5.smoothScrollBy() 与 fling()

6. 其他相关类

参考网址:http://mobile.51cto.com/design-375889.htm
http://www.cnblogs.com/wanqieddy/archive/2012/05/05/2484534.html

VelocityTracker 速度追踪器

追踪用户手指在屏幕上的滑动速度。当你要跟踪一个touch事件的时候,使用obtain()方法得到这个类的实例,然后 用addMovement(MotionEvent)函数将接受到的motionEvent加入到VelocityTracker类实例中。

使用computeCurrentVelocity(int)初始化速率的 单位,并获得当前的事件的速率;然后使用getXVelocity() 或getXVelocity()获得横向和竖向的速率。

ViewConfiguration

定义了android的许多标准的常量(UI的超时、大小和距离等)。

public int getScaledEdgeSlop() 获得一个触摸移动的最小像素值。也就是说,只有超过了这个值,才代表我们该滑屏处理了。

public static int getLongPressTimeout() 获得一个执行长按事件监听(onLongClickListener)的值。也就是说,对某个View按下触摸时,只有超过了这个时间值在,才表示我们该对该View回调长按事件了;否则,小于这个时间点松开手指,只执行onClick监听。

GestureDetector 手势识别器

追踪用户手指在屏幕上的滑动方向

Scroller的方法startScroll、fling、computeScrollOffset_scroller.startscroll-CSDN博客 (2024)
Top Articles
Latest Posts
Article information

Author: Dong Thiel

Last Updated:

Views: 5756

Rating: 4.9 / 5 (59 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Dong Thiel

Birthday: 2001-07-14

Address: 2865 Kasha Unions, West Corrinne, AK 05708-1071

Phone: +3512198379449

Job: Design Planner

Hobby: Graffiti, Foreign language learning, Gambling, Metalworking, Rowing, Sculling, Sewing

Introduction: My name is Dong Thiel, I am a brainy, happy, tasty, lively, splendid, talented, cooperative person who loves writing and wants to share my knowledge and understanding with you.