findViewById如何初始化视图

时间:2013-02-10 18:22:14

标签: android

我刚刚为findViewById困惑的人写了一个答案,我意识到我的理解存在差距。这个问题只是为了知识和好奇心。

考虑一下:

button = (Button)findViewById(R.id.button);

findViewById返回View的实例,然后将其强制转换为目标类。到目前为止一切都很好。

要设置视图,findViewById会从相关XML声明中的参数构造AttributeSet,并将其传递给View的构造函数。

然后我们将View个实例投射到Button

AttributeSet如何依次传递给Button构造函数?

[编辑]

所以我很困惑:)。重点是当布局膨胀时,视图层次结构已经包含视图后代类的实例。 findViewById只返回对它的引用。当你想到它时显而易见 - doh ..

1 个答案:

答案 0 :(得分:6)

我认为findViewById()不构造或实例化View。对于具有匹配ID的视图,它将在已充气布局的视图层次结构中进行搜索。此方法对ViewViewGroup的工作方式不同。

来自Android源代码:

如果此视图具有给定的id或null,则

View.findViewById()返回相同的View对象,它会调用:

protected View findViewTraversal(int id) {
    if (id == mID) {
        return this;
    }
    return null;
}

ViewGroup.findViewById()遍历子视图并在这些视图上调用相同的方法,它调用:

 protected View findViewTraversal(int id) {
    if (id == mID) {
        return this;
    }

    final View[] where = mChildren;
    final int len = mChildrenCount;

    for (int i = 0; i < len; i++) {
        View v = where[i];

        if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
            v = v.findViewById(id);

            if (v != null) {
                return v;
            }
        }
    }

    return null;
}