探究LayoutInflater和RecyclerView中item設(shè)置寬高無效

1. LayoutInflater是做什么的

Instantiates a layout XML file into its corresponding {@link android.view.View}objects. 
實(shí)例化一個(gè)布局XML文件轉(zhuǎn)換為相應(yīng)的{ @link android.view。視圖對象};

在Android開發(fā)中LayoutInflater經(jīng)常要用到,F(xiàn)ragment睡互,adapter中的視圖都是需要LayoutInflater將XML文件轉(zhuǎn)換為View對象

2. 獲取LayoutInflater對象

獲取LayoutInflater對象有三種方法

(1)getLayoutInflater()
調(diào)用Activity的getLayoutInflater()

(2)LayoutInflater.from(context)
調(diào)用LayoutInflater的靜態(tài)方法從context中獲取LayoutInflater對象

(3)(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
調(diào)用系統(tǒng)服務(wù)獲取LayoutInflater對象

3.將XML文件轉(zhuǎn)換為View對象

最常用的做法

 View view = layoutinflater.inflate(R.layout.XXX,null);
到此為止享甸,上述的方法基本能實(shí)現(xiàn)布局從xml轉(zhuǎn)換為想要的View對象
但是前幾天在做RecyclerView的時(shí)候發(fā)現(xiàn)一個(gè)問題族壳,如下

4.RecyclerView中item設(shè)置寬高無效

item_recyclerview.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:padding="20dp"
                android:background="#44ff0000">

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="#ffffff"
        android:textSize="26sp"/>

</RelativeLayout>

recyclerview的adapter中布局轉(zhuǎn)換

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = lif.inflate(R.layout.item_recyclerview,null);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

簡單的item布局徒溪,實(shí)現(xiàn)的效果如下

image.png

發(fā)現(xiàn)明明設(shè)置了寬度是match_parent,顯示出來的效果確實(shí)有點(diǎn)像wrap_content
然后調(diào)整item的高度金顿,發(fā)現(xiàn)也是不起作用的
在檢查代碼之后找不到出現(xiàn)問題的原因臊泌,百度了一波找到原因
※在布局轉(zhuǎn)換的時(shí)候使用
View view = layoutinflater.inflate(R.layout.item_XXX,ViewGroup,false);
修改之后,效果如下


符合預(yù)期效果揍拆。

※問題:

(1)為什么使用三個(gè)參數(shù)的inflate方法就能實(shí)現(xiàn)效果渠概?
(2)inflate三個(gè)參數(shù)和兩個(gè)參數(shù)有什么區(qū)別?

5.LayoutInflater.inflate方法分析

inflate有重載4個(gè)方法

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root)
public View inflate(XmlPullParser parser, @Nullable ViewGroup root)
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) 

查看源碼發(fā)現(xiàn)不管是三個(gè)參數(shù)還是兩個(gè)參數(shù)的inflate方法
最終是實(shí)現(xiàn)了
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)
attachToRoot的值是根據(jù) root != null來賦值

/**
     * Inflate a new view hierarchy from the specified XML node. Throws
     * {@link InflateException} if there is an error.
     * <p>
     * <em><strong>Important</strong></em>   For performance
     * reasons, view inflation relies heavily on pre-processing of XML files
     * that is done at build time. Therefore, it is not currently possible to
     * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
     * 
     * @param parser XML dom node containing the description of the view
     *        hierarchy.
     * @param root Optional view to be the parent of the generated hierarchy (if
     *        <em>attachToRoot</em> is true), or else simply an object that
     *        provides a set of LayoutParams values for root of the returned
     *        hierarchy (if <em>attachToRoot</em> is false.)
     * @param attachToRoot Whether the inflated hierarchy should be attached to
     *        the root parameter? If false, root is only used to create the
     *        correct subclass of LayoutParams for the root view in the XML.
     * @return The root View of the inflated hierarchy. If root was supplied and
     *         attachToRoot is true, this is root; otherwise it is the root of
     *         the inflated XML file.
     */
    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)第一個(gè)參數(shù)parser

parser:xml文件
如果傳入的是layout的id嫂拴,會調(diào)用
final XmlResourceParser parser = res.getLayout(resource)播揪;轉(zhuǎn)換成xml文件

(2)第二個(gè)參數(shù)root,第三個(gè)參數(shù)attachToRoot

  • root不為空
    和第三個(gè)參數(shù)attachToRoot有關(guān)
    ① 如果attachToRoot為true
    root成為inflate出來的view對象的父布局
    ② 如果attachToRoot為false
    inflate出來的view的根布局提供LayoutParams參數(shù)的控件
final AttributeSet attrs = Xml.asAttributeSet(parser);
....
 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);
                        }
                    }

當(dāng)root不為空筒狠,attachToRoot為false時(shí)候猪狈。
獲得xml文件中的屬性
通過createViewFromTag生成View
再通過generateLayoutParams(attrs)生成layoutparams參數(shù)
設(shè)置到view中,使得view有l(wèi)ayoutParams

  • root為空(null)
    ※不指定父布局辩恼,那么inflate出來的view對象的根布局的某些參數(shù)會失效雇庙,比如Layout_width和Layout_height會失效

6.寫后感

源碼封裝的太好了,代碼跳來跳去灶伊,對于不經(jīng)辰埃看源碼的我來說很容易看不下去。不過還是硬著頭皮慢慢看下去聘萨,不要往深層去看竹椒,有些可以選擇性忽略,只要看懂注釋大概懂得米辐,等知識累積的更多了相信再去重新解讀源碼會有新收獲胸完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末书释,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舶吗,更是在濱河造成了極大的恐慌征冷,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誓琼,死亡現(xiàn)場離奇詭異检激,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)腹侣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門叔收,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人傲隶,你說我怎么就攤上這事饺律。” “怎么了跺株?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵复濒,是天一觀的道長。 經(jīng)常有香客問我乒省,道長巧颈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任袖扛,我火速辦了婚禮砸泛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛆封。我一直安慰自己唇礁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布惨篱。 她就那樣靜靜地躺著盏筐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砸讳。 梳的紋絲不亂的頭發(fā)上机断,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音绣夺,去河邊找鬼吏奸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛陶耍,可吹牛的內(nèi)容都是我干的奋蔚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼泊碑!你這毒婦竟也來了坤按?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤馒过,失蹤者是張志新(化名)和其女友劉穎臭脓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腹忽,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡来累,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窘奏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘹锁。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖着裹,靈堂內(nèi)的尸體忽然破棺而出领猾,到底是詐尸還是另有隱情,我是刑警寧澤骇扇,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布摔竿,位于F島的核電站,受9級特大地震影響少孝,放射性物質(zhì)發(fā)生泄漏继低。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一韭山、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冷溃,春花似錦钱磅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凿歼,卻和暖如春褪迟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背答憔。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工味赃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虐拓。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓心俗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子城榛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

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

  • 前言 這個(gè)問題很早之前就碰到過揪利,后來通過google找到了解決辦法,也就沒有去管它了狠持,直到最近有朋友問到這個(gè)問題疟位,...
    依然范特稀西閱讀 28,180評論 22 119
  • 原文地址:http://www.reibang.com/p/de7f651170be 一、簡述 LayoutInf...
    AFinalStone閱讀 4,057評論 1 7
  • RecyclerView Item 布局寬高無效問題探究 前言 這個(gè)問題很早之前就碰到過喘垂,后來通過google找到...
    TinyMen閱讀 423評論 0 0
  • 用法獲取LayoutInflater 首先要注意LayoutInflater本身是一個(gè)抽象類甜刻,我們不可以直接通過n...
    我本和圖閱讀 869評論 0 0
  • 工作日志 所收任務(wù) 整理“水質(zhì)預(yù)警預(yù)報(bào)信息平臺”需求,形成需求分析文檔 完成情況 基本完成初步需求分析文檔王污,但需要...
    錢佳辰_Hangzhou閱讀 127評論 0 0