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

来源:互联网 发布:软件架构师真题 编辑:程序博客网 时间:2024/05/17 07:14


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()



明天继续奋斗





原创粉丝点击