可以看出來使用兩個參數時,它的內部也是調用了3個參數的方法。 如果我們使用LayoutInflater.from(context).inflate(R.layout.recycle_foot_item,null); 則實際上是調用了LayoutInflater.from(context).infla ...
轉載請標明出處:https://www.cnblogs.com/tangZH/p/7074853.html
很多人都用過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添加進來。