LayoutInflater.inflate()解析

布局加載器加載視圖的方法有以下幾種:

  1. public View inflate(int resource, ViewGroup root)
  2. public View inflate(int resource, ViewGroup root, boolean attachToRoot)
  3. public View inflate(XmlPullParser parser, ViewGroup root)
  4. public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

resource會(huì)通過(guò)Pull解析器被解析成XmlPullParser類型的parser, 故只需要看第四個(gè)方法就知道是怎么回事了!一般我們使用它的時(shí)候有三種使用方法:

  1. inflate(parser, null, false);
  2. inflate(parser, root, false);
  3. inflate(parser, root, true);

//在API25源碼復(fù)制
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
    synchronized (mConstructorArgs) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

        final Context inflaterContext = mContext;
        final AttributeSet attrs = Xml.asAttributeSet(parser);
        Context lastContext = (Context) mConstructorArgs[0];
        mConstructorArgs[0] = inflaterContext;
        View result = root;

        try {
            // Look for the root node.
            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG &&
                    type != XmlPullParser.END_DOCUMENT) {
                // Empty
            }

            if (type != XmlPullParser.START_TAG) {
                throw new InflateException(parser.getPositionDescription()
                        + ": No start tag found!");
            }

            final String name = parser.getName();

            if (DEBUG) {
                System.out.println("**************************");
                System.out.println("Creating root view: "
                        + name);
                System.out.println("**************************");
            }

            if (TAG_MERGE.equals(name)) {
                if (root == null || !attachToRoot) {
                    throw new InflateException("<merge /> can be used only with a valid "
                            + "ViewGroup root and attachToRoot=true");
                }

                rInflate(parser, root, inflaterContext, attrs, false);
            } else {
                // Temp is the root view that was found in the xml
                final View temp = createViewFromTag(root, name, inflaterContext, attrs);

                ViewGroup.LayoutParams params = null;

                if (root != null) {
                    if (DEBUG) {
                        System.out.println("Creating params from root: " +
                                root);
                    }
                    // Create layout params that match root, if supplied
                    params = root.generateLayoutParams(attrs);
                    if (!attachToRoot) {
                        // Set the layout params for temp if we are not
                        // attaching. (If we are, we use addView, below)
                        temp.setLayoutParams(params);
                    }
                }

                if (DEBUG) {
                    System.out.println("-----> start inflating children");
                }

                // Inflate all children under temp against its context.
                rInflateChildren(parser, temp, attrs, true);

                if (DEBUG) {
                    System.out.println("-----> done inflating children");
                }

                // We are supposed to attach all the views we found (int temp)
                // to root. Do that now.
                if (root != null && attachToRoot) {
                    root.addView(temp, params);
                }

                // Decide whether to return the root that was passed in or the
                // top view found in xml.
                if (root == null || !attachToRoot) {
                    result = temp;
                }
            }

        } catch (XmlPullParserException e) {
            final InflateException ie = new InflateException(e.getMessage(), e);
            ie.setStackTrace(EMPTY_STACK_TRACE);
            throw ie;
        } catch (Exception e) {
            final InflateException ie = new InflateException(parser.getPositionDescription()
                    + ": " + e.getMessage(), e);
            ie.setStackTrace(EMPTY_STACK_TRACE);
            throw ie;
        } finally {
            // Don't retain static reference on context.
            mConstructorArgs[0] = lastContext;
            mConstructorArgs[1] = null;

            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }

        return result;
    }
}
  1. inflate(parser, null, false);
  2. inflate(parser, root, false);
  3. inflate(parser, root, true);

第一種情況:

// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
    result = temp;
}

temp是啥筒繁?往前看:

// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs);

temp is the root view that was found in the xml.源碼中的注釋寫的很清晰噩凹。temp就是你加載的那個(gè)xml文件的根視圖巴元。也就是說(shuō)第二個(gè)參數(shù)root如果是空就直接返回xml文件里的根視圖毡咏。接下來(lái)看看root!=null的情況:


if (root != null) {
    if (DEBUG) {
        System.out.println("Creating params from root: " +
                root);
    }
    // Create layout params that match root, if supplied
    params = root.generateLayoutParams(attrs);
    if (!attachToRoot) {
        // Set the layout params for temp if we are not
        // attaching. (If we are, we use addView, below)
        temp.setLayoutParams(params);
    }
    ...

    // Decide whether to return the root that was passed in or the
    // top view found in xml.
    if (root == null || !attachToRoot) {
    result = temp;
}


}

現(xiàn)在更清晰了,當(dāng)我們傳進(jìn)來(lái)的root不是null逮刨,并且第三個(gè)參數(shù)是false的時(shí)候呕缭,這個(gè)temp會(huì)使用root生成的layoutParams,并作為返回值返回了修己。而當(dāng)我們?cè)O(shè)置root為空的時(shí)候恢总,沒(méi)有設(shè)置LayoutParams參數(shù)的temp對(duì)象,作為返回值返回了睬愤。這時(shí)候我們發(fā)現(xiàn)只要是root為null或者attachToRoot為false都會(huì)將root返回片仿,那么inflate(parser, null, false)和inflate(parser, root, false)又有什么區(qū)別呢?實(shí)際上這個(gè)root是作為一個(gè)協(xié)助生成view的容器尤辱,如果我想讓生成的布局的根節(jié)點(diǎn)有效砂豌,又不想讓它處于某一個(gè)容器中,那我就可以設(shè)置root!=null光督,而attachToRoot為false阳距。由此可見(jiàn)root會(huì)協(xié)助第一個(gè)參數(shù)所指定布局的根節(jié)點(diǎn)生成布局參數(shù)!
??再回頭看代碼结借,當(dāng)root!=null,attachToRoot為true時(shí):

// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
    root.addView(temp, params);
}

很清楚筐摘,當(dāng)attachToRoot為true時(shí),會(huì)將第一個(gè)參數(shù)所指定的布局添加到第二個(gè)參數(shù)的View中。
??總結(jié)一下:當(dāng)root==null時(shí)咖熟,直接返回要加載布局文件的根視圖圃酵;當(dāng)root!=null時(shí),如果attachToRoot==false球恤,系統(tǒng)會(huì)通過(guò)將root作為一個(gè)容器,協(xié)助生成view咽斧;如果attachToRoot==true堪置,會(huì)將生成的view添加到root中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末张惹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坎匿,更是在濱河造成了極大的恐慌雷激,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件承桥,死亡現(xiàn)場(chǎng)離奇詭異根悼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)剩彬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門喉恋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人母廷,你說(shuō)我怎么就攤上這事轻黑。” “怎么了徘意?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵苔悦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我椎咧,道長(zhǎng)玖详,這世上最難降的妖魔是什么把介? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蟋座,結(jié)果婚禮上拗踢,老公的妹妹穿的比我還像新娘。我一直安慰自己向臀,他們只是感情好巢墅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著券膀,像睡著了一般君纫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芹彬,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天蓄髓,我揣著相機(jī)與錄音,去河邊找鬼舒帮。 笑死会喝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玩郊。 我是一名探鬼主播肢执,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼译红!你這毒婦竟也來(lái)了预茄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤临庇,失蹤者是張志新(化名)和其女友劉穎反璃,沒(méi)想到半個(gè)月后昵慌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體假夺,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年斋攀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了已卷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡淳蔼,死狀恐怖侧蘸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鹉梨,我是刑警寧澤讳癌,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站存皂,受9級(jí)特大地震影響晌坤,放射性物質(zhì)發(fā)生泄漏逢艘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一骤菠、第九天 我趴在偏房一處隱蔽的房頂上張望它改。 院中可真熱鬧,春花似錦商乎、人聲如沸央拖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鲜戒。三九已至,卻和暖如春抹凳,著一層夾襖步出監(jiān)牢的瞬間袍啡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工却桶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留境输,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓颖系,卻偏偏與公主長(zhǎng)得像嗅剖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘁扼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一信粮、適用場(chǎng)景 ListViewListview是一個(gè)很重要的組件,它以列表的形式根據(jù)數(shù)據(jù)的長(zhǎng)自適應(yīng)展示具體內(nèi)容,用...
    Geeks_Liu閱讀 10,669評(píng)論 1 28
  • 原文地址:http://www.reibang.com/p/de7f651170be 一趁啸、簡(jiǎn)述 LayoutInf...
    AFinalStone閱讀 4,062評(píng)論 1 7
  • 學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話强缘,歡迎加入Android學(xué)習(xí)交流群,群號(hào)碼:364595326 我們一...
    kingZXY2009閱讀 336評(píng)論 0 0
  • 有段時(shí)間沒(méi)寫博客了不傅,感覺(jué)都有些生疏了呢旅掂。最近繁忙的工作終于告一段落,又有時(shí)間寫文章了访娶,接下來(lái)還會(huì)繼續(xù)堅(jiān)持每一周篇的...
    justin_pan閱讀 550評(píng)論 0 2
  • 出門就被涼風(fēng)撲了個(gè)滿懷商虐,一縷小情緒縈上心頭。驅(qū)車上路崖疤,卻發(fā)現(xiàn)秘车,天象異常美好。朝霞與與路面相接劫哼,橙灰與淺藍(lán)交融叮趴。伴隨...
    亞男1987閱讀 212評(píng)論 1 2