10

findViewById で混乱している人への回答を書いたところ、自分の理解にギャップがあることに気付きました。この質問は、知識と好奇心のみを対象としています。

このことを考慮:

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

findViewByIdのインスタンスを返しView、それがターゲット クラスにキャストされます。これまでのところすべて順調です。

ビューをセットアップするために、 のコンストラクターに渡す関連付けられた XML 宣言のパラメーターから を構築しfindViewByIdます。AttributeSetView

View次に、インスタンスをにキャストしますButton

get はどのようにコンストラクターAttributeSetに渡されますか?Button

[編集]

だから私は混乱していた:)。全体的なポイントは、レイアウトがインフレートされると、ビュー階層にはビューの子孫クラスのインスタンスが既に含まれているということです。findViewById は単にそれへの参照を返します。あなたがそれについて考えるとき明らかです-ド..

4

2 に答える 2

14

findViewById何もしません。ビュー階層を調べて、要求されたビューへの参照を返すだけviewIdです。Viewはすでに作成され、存在しています。ビューを呼び出さなければfindViewById、何も変わりません。

ビューは によって膨張しLayoutInflatorます。xml レイアウトを呼び出すsetContentViewと、解析され、ビュー階層が作成されます。

によって Button のコンストラクタに渡される属性LayoutInflaterLayoutInflator のソース コードを確認してください。

于 2013-02-10T18:26:53.257 に答える
6

findViewById()ビューを構築またはインスタンス化するとは思わない。既に膨張したレイアウトのビュー階層で、一致する ID を持つビューを検索しViewますViewGroup

Androidソースコードから:

View.findViewById()このビューが指定された id または null を持つ場合、同じ 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;
}
于 2013-02-10T18:33:16.107 に答える