有一次面試,問到inflate()三個參數,平時開發經常用,但是具體細節很少追究,瞬間懵B了,找到一個比較好的文章,摘錄下來。
摘自:https://www.jianshu.com/p/c92243287793
相信大家都用過LayoutInflater(布局填充器),今天主要說下我對inflate方法的使用理解。
inflate方法有如下兩種:
public View inflate (int resource, ViewGroup root) public View inflate (int resource, ViewGroup root, boolean attachToRoot)
查看源碼,我們發現兩個參數的方法內部引用了三個參數的方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); }
我們將兩個參數的方法轉化為三個參數的方法。如下:
inflater.inflate(R.layout.item, null); —————>inflater.inflate(R.layout.item, null, null != null); 相當於: inflater.inflate(R.layout.item, null, false); inflater.inflate(R.layout.item, parent); —————>inflater.inflate(R.layout.item, parent, parent!= null); 相當於: inflater.inflate(R.layout.item, parent, true);
所以我們只需要研究四個方法
inflater.inflate(R.layout.item, null, true); inflater.inflate(R.layout.item, null, false); inflater.inflate(R.layout.item, parent, true); inflater.inflate(R.layout.item, parent, false);
首先我先說下我對每個參數的理解
第一個參數:想要添加的布局
第二個參數:想要添加到哪個布局上面
(null和有值的區別 null時第一個參數中最外層的布局大小無效,有值的時候最外層的布局大小有效)
第三個參數:是否直接添加到第二個參數布局上面
(true代表layout文件填充的View會被直接添加進parent,而傳入false則代表創建的View會以其他方式被添加進parent)
下面我們來對四個方法一一講解
為了更好的理解我准備了一個簡單的案例,我的Activity的布局如下:一個超簡單的RelativeLayout 布局,我們在這理解為父布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl" android:layout_width="match_parent" android:layout_height="match_parent"> </RelativeLayout>
我還有一個布局layout.xml如下:有一個寬度高度為200dp的LinearLayout ,LinearLayout 中有一個Button按鈕。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="150dp" android:layout_height="150dp" android:background="#ff0000"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="開開心心每一天" /> </LinearLayout>
布局准好了,下面進入正題。我要把layout.xml這個布局文件添加到我的activity的布局中,我的Activity的代碼如下:

為了看到四個方法有什么不一樣,我依次替換圈起來的代碼,查看展示效果:
1:inflater.inflate(R.layout.item, null, true);

2:inflater.inflate(R.layout.item, null, false);

3:inflater.inflate(R.layout.item, parent, true);
使用該方法時rl.addView(view);代碼報錯,錯誤異常如下
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
意思是非法狀態異常,指定的child已經有一個父容器了。你必須先用chile的父容器調用removeView()。
源碼中對第三個參數的解釋是
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.
attachToRoot傳入true代表layout文件填充的View會被直接添加進parent,而傳入false則代表創建的View會以其他方式被添加進parent。
解決方法
刪除rl.addView(view);這一行代碼,然后運行展示效果

4:inflater.inflate(R.layout.item, parent, false);

總結
從案例中我們可以看到1、2這兩種方式運行結果一樣,第二個參數傳null會使要添加的布局視圖中根視圖的寬高設置失效,在使用這種方式的時候會造成我們無形中多加一層布局,為了使其子view顯示相應高度。在這里不推薦使用
3這種方式我們在使用的時候一定要注意,它會使代表layout文件填充的View會被直接添加進parent,如果我們使用這種方式后,在執行addView()方法就會造成上面的錯誤。
推薦使用第四種方式 inflater.inflate(R.layout.item, parent, false);
以上是我對inflate方法的使用理解,有什么不對的地方,大家積極留言,我看到后會第一時間回復大家,最后祝大家每天都有個好心情。
作者:石頭1314
鏈接:https://www.jianshu.com/p/c92243287793
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。