天天记录 - 从源码分析ScrollBy和ScrollTo仅执行onDraw方法



1. 先来看看View.scrollBy的源码


    public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

从注释中可以获知,scrollBy 方法把视图移动到当前的相应偏移位置。其中调用scrollTo

2. 查看View.scrollTo源码
    public void scrollTo(int x, int y) {
        if (mScrollX != x || mScrollY != y) {
            int oldX = mScrollX;
            int oldY = mScrollY;
            mScrollX = x;
            mScrollY = y;
            invalidateParentCaches();
            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
            if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }
        }
    }

View.scrollTo方法调用  awakenScrollBars


3. 查看view.awakenScrollBars

    protected boolean awakenScrollBars() {
        return mScrollCache != null &&
                awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
    }

awakenScrollBars


4. 查看View.awakenScrollBars(int startDelay, boolean invalidate)
    protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
        final ScrollabilityCache scrollCache = mScrollCache;

        ......

        if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {

           ......

            return true;
        }

        return false;
    }

单从字面意思理解isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled() 当前视图没有显示横向和纵向scrollbar ,所以4方法返回false。
3中调用4方法获取其返回值false,2中调用3 获取返回值false ,2中if判断!awakenScrollBars() 为true,执行postInvalidateOnAnimation

4. 查看view.postInvalidateOnAnimation
    /**
     * <p>Cause an invalidate to happen on the next animation time step, typically the
     * next display frame.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     *
     * @see #invalidate()
     */
    public void postInvalidateOnAnimation() {
        // We try only with the AttachInfo because there's no point in invalidating
        // if we are not attached to our window
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
        }
    }

从注释中得知会最终调用invalidate方法

最终会调用 android.view.ViewRootImpl.performTraversals()



明天继续 奋斗





你可能感兴趣的:(天天记录 - 从源码分析ScrollBy和ScrollTo仅执行onDraw方法)