View 的 requestLayout 发起的重绘流程源码分析(Android Q)

View 的 requestLayout 发起的重绘流程源码分析(Android Q)


我们平时经常会调用 View 类的 requestLayout 方法更新视图,那么它又是如何发起的重绘逻辑呢?

View 的 requestLayout 方法:

    public void requestLayout() {
        ……
        if (mParent != null && !mParent.isLayoutRequested()) {
            //调用父视图的 requestLayout 方法
            mParent.requestLayout();
        }
        ……
    }

该方法进行了一些属性设置,接下来调用了父视图的 requestLayout 方法。该方法一直会顺着视图树向上调用,一直到根视图,也就是 DecorView。但最终是调用到 DecorView 的 requestLayout 方法吗?

我们先来看 mParent 在什么地方赋值的?

View 的 assignParent 方法

    protected ViewParent mParent;
    void assignParent(ViewParent parent) {
        if (mParent == null) {
            mParent = parent;
        } else if (parent == null) {
            mParent = null;
        } else {
            throw new RuntimeException("view " + this + " being added, but"
                    + " it already has a parent");
        }
    }

mParent 是通过 assignParent 的参数设置的,又是谁调用了 assignParent 方法呢?

ViewRootImpl 的 setView 方法:

我们回一下,ViewRootImpl 的 setView 方法是在 DecorView 要添加到 Window 时调用的。

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView){
        ……
        view.assignParent(this);
        ……
    }

其实是在 ViewRootImpl 的 setView 方法中,调用了 View 的 assignParent 方法,参数呢,就是 ViewRootImpl 对象。也就是说 DecorView 的 mParent 是 ViewRootImpl 对象。

所以,View 的 requestLayout 方法,最终通过它的 mParent 逐级冒泡,最终调用到 ViewRootImpl 中的 requestLayout 方法。这不就和本文前半部分的内容接上了吗,这两种视图显示过程,都是通过 ViewRootImpl 中的 requestLayout 方法发起的。

总结


View 类的 requestLayout 方法更新视图,是如何发起的重绘逻辑呢?

  1. ViewRootImpl 的 setView 方法中,调用了 View 的 assignParent 方法,参数呢,就是 ViewRootImpl 对象。也就是说 DecorView 的 mParent 是 ViewRootImpl 对象。

  2. View 的 requestLayout 方法,最终通过它的 mParent 逐级冒泡,最终调用到 ViewRootImpl 中的 requestLayout 方法。所以本质上来讲,它是通过 ViewRootImpl 中的 requestLayout 方法发起的。


PS:更多分析文章,请查看系列文章–>《Android底层原理解析》
PS:更多分析文章,请查看系列文章–>《Android底层原理解析》
PS:更多分析文章,请查看系列文章–>《Android底层原理解析》

猜你喜欢

转载自blog.csdn.net/u011578734/article/details/110958596
今日推荐