LayoutInflater.inflate()方法兩個參數和三個參數


轉載請標明出處:https://www.cnblogs.com/tangZH/p/7074853.html 
更多精美文章:http://77blogs.com/?p=489

很多人都用過LayoutInflater(布局填充器)

對於我來說通常使用下面兩種:
LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,null);
LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,parent,false);

那么兩個參數與三個參數究竟有什么區別呢?

我們進去源碼看一下兩個參數時的代碼:
 public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
        return inflate(resource, root, root != null);
    }

可以看出來使用兩個參數時,它的內部也是調用了3個參數的方法。


如果我們使用LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,null);

則實際上是調用了LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,null,null!=null);

等同於:LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,null,false);

 

如果我們使用LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,parent);

則實際上是調用了LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,parent,parent!=null);

等同於:LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,parent,true);

 

 我們再來看看三個參數的方法的源碼:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
        final Resources res = getContext().getResources();
        if (DEBUG) {
            Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                    + Integer.toHexString(resource) + ")");
        }

        final XmlResourceParser parser = res.getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
        } finally {
            parser.close();
        }
    }

在里面調用了
inflate(parser, root, attachToRoot);方法,在源碼中可以看到,inflate(parser, root, attachToRoot);方法中有下面代碼:

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);
         }
}
.
.
.
// 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);
}

從上面可以看出:
如果第二個和第三個參數均不為空的話,即root不為null,而attachToRoot為true的話那么我們執行完LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,parent,true);之后,R.layout.recycle_foot_item就已經被添加進去parent中了,我們不能再次調用parent.add(View view)這個方法,否則會拋出異常。

 

那么root不為null,attachToRoot為false是代表什么呢?我們可以肯定的說attachToRoot為false,那么我們不將第一個參數的view添加到root中,那么root有什么作用?其實root決定了我們的設置給第一個參數view的布局的根節點的layout_width和layout_height屬性是否有效。我們在開發的過程中給控件所指定的layout_width和layout_height到底是什么意思?該屬性的表示一個控件在容器中的大小,就是說這個控件必須在容器中,這個屬性才有意義,否則無意義。所以如果我們不給第一個參數的view指定一個父布局,那么該view的根節點的寬高屬性就失效了。

如果我想讓第一個參數view的根節點有效,又不想讓其處於某一個容器中,那我就可以設置root不為null,而attachToRoot為false。這樣,指定root的目的也就很明確了,即root會協助第一個參數view的根節點生成布局參數,只有這一個作用。

但是這個時候我們要手動地把view添加進來。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM