要理解Android的原理,最好的方法是通过源码来分析。这次又来了,看看Scroller到底是什么?

Scroller就是一个滚动的辅助类,它只存储View的位置和计算出位置,并没有真正移动View,讨厌的是Scroller.startScroll()从名字上误导人了,刚开始还以为是这个方法移动的呢。

public class Scroller  {    private int mMode;    private int mStartX;    private int mStartY;    private int mFinalX;    private int mFinalY;    private int mMinX;    private int mMaxX;    private int mMinY;    private int mMaxY;    private int mCurrX;    private int mCurrY;    private long mStartTime;    private int mDuration;    private float mDurationReciprocal;    private float mDeltaX;    private float mDeltaY;    private boolean mFinished;    private Interpolator mInterpolator;    private boolean mFlywheel;    private float mVelocity;    private float mCurrVelocity;    private int mDistance;    private float mFlingFriction = ViewConfiguration.getScrollFriction();    private static final int DEFAULT_DURATION = 250;    private static final int SCROLL_MODE = 0;    private static final int FLING_MODE = 1;    private static float DECELERATION_RATE = (float) (Math.log(0.78) / Math.log(0.9));    private static final float INFLEXION = 0.35f; // Tension lines cross at (INFLEXION, 1)    private static final float START_TENSION = 0.5f;    private static final float END_TENSION = 1.0f;    private static final float P1 = START_TENSION * INFLEXION;    private static final float P2 = 1.0f - END_TENSION * (1.0f - INFLEXION);    private static final int NB_SAMPLES = 100;    private static final float[] SPLINE_POSITION = new float[NB_SAMPLES + 1];    private static final float[] SPLINE_TIME = new float[NB_SAMPLES + 1];    private float mDeceleration;    private final float mPpi;    // A context-specific coefficient adjusted to physical values.    private float mPhysicalCoeff;

Scroller一开始就是一大堆变量,名字可以看出就是一些位置X,Y啊等等,还有滚动的状态,速度值。主要的方法也是getXXX和setXXX,这就是获得属性而已。

关键的两个方法如下:

/**     * Start scrolling by providing a starting point, the distance to travel,     * and the duration of the scroll.     *      * @param startX Starting horizontal scroll offset in pixels. Positive     *        numbers will scroll the content to the left.     * @param startY Starting vertical scroll offset in pixels. Positive numbers     *        will scroll the content up.     * @param dx Horizontal distance to travel. Positive numbers will scroll the     *        content to the left.     * @param dy Vertical distance to travel. Positive numbers will scroll the     *        content up.     * @param duration Duration of the scroll in milliseconds.     */    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;    }

这是通过给定的起始和结束的xy值和时间,计算出对应时间应该对应的坐标。一看都是赋值的语句,都没涉及到View的移动。


另一个是:

/**     * Start scrolling based on a fling gesture. The distance travelled will     * depend on the initial velocity of the fling.     *      * @param startX Starting point of the scroll (X)     * @param startY Starting point of the scroll (Y)     * @param velocityX Initial velocity of the fling (X) measured in pixels per     *        second.     * @param velocityY Initial velocity of the fling (Y) measured in pixels per     *        second     * @param minX Minimum X value. The scroller will not scroll past this     *        point.     * @param maxX Maximum X value. The scroller will not scroll past this     *        point.     * @param minY Minimum Y value. The scroller will not scroll past this     *        point.     * @param maxY Maximum Y value. The scroller will not scroll past this     *        point.     */    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 = FloatMath.sqrt(dx * dx + dy * 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 = FloatMath.sqrt(velocityX * velocityX + velocityY * 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);    }

fling,这个可怕的家伙又来了,其实也没什么,手指放开那一刻,由于View的滚动还有速度,所以这是根据速度来计算接下来的View的位置。


那么,这个Scroller都没有移动Veiw,还要它做什么呢?它就是辅助移动的,我们可以随时通过getCurrX和getCurrY获得View的位置,然后。。。使用ScrollTo来滚动这个Veiw.但是要注意的是,ScrollTo是针对View里面的内容的,如果是是LinearLayout.ScrollTo(),LinearLayout里面的东西全部移动,那如果是TextView.ScrollTo()呢,只是TextView里面的内容移动而已啦~,TextView还是原地不动的。

更多相关文章

  1. 【android之ScrollView滚动视图】
  2. 使用 Android(安卓)Jetpack 加快应用开发速度
  3. Android(安卓)vector 标签
  4. android之ScrollView里嵌套ListView
  5. TextView文字横向自动滚动(跑马灯)
  6. Android仿qq回弹阻尼ScrollView
  7. Android简单记录和恢复ListView滚动位置的方法
  8. 加快Android(安卓)Studio的编译速度
  9. Gallery自动循环滚动以及手动滚动的平滑切换(一)

随机推荐

  1. Android studio在Android 6.0下继续使用A
  2. TextView 中文文档
  3. 在android studio中用SQLiteOpenHelper()方
  4. 汉字先生-----初学android时做的小游戏
  5. android 联系人数据库一些知识点
  6. Android-StateListDrawable(状态选择器)
  7. Android UI设计:Button与RadoiButton
  8. Android UI开发神兵利器之Android Action
  9. Windows7中Android模拟器无法打开
  10. 如何检查Android后台服务线程(Service类)是