吐槽
发现好像这个动态加载布局的方法,,参数这块很迷啊,就去网上查了一下这块到底是怎么用的,一查才发现这块很神奇,就总结了一下,防止自己以后出问题。
inflate方法
它是抽象类LayoutInflater动态加载布局所用到的方法
这个方法重载有4种,传入的参数不一样,这个也不一样
两个参数的
public View inflate (int resource, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root)
//第一个参数是子布局,第二个参数是要加载进去的父布局
三个参数的
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
//第一个参数是子布局,第二个参数是要加载进去的父布局,第三个就是
是否将载入的视图绑定到根视图中
测试用三个参数的
首先看下我们的布局
父布局:activity_layoutlinflate.xml
就是一个很简单的LinearLayout布局,底色是红色的
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LayoutlinflateActivity"
android:background="#66ff0000"
android:id="@+id/ll_addView1"
android:orientation="vertical">
</LinearLayout>
然后就是我们要加载进去的布局:additem_layout.xml
黑色的布局里面有个按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/ll_item"
android:background="#030303">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
第一种情况:root不为null,attachToRoot为true
直接在活动里面
setContentView(R.layout.activity_layoutlinflate);
LinearLayout item = (LinearLayout)findViewById(R.id.ll_addView1);//父布局
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.additem_layout,item,true);
结果连addview方法都没用就把这个第一布局加入到第二个布局文件里面了
效果如下
为什么练addview方法都没用就把子布局加载进来了呢?
我们在代码后面加上一段代码
item.addView(view);
然后结果是,,报错
所以由上面推出true的作用就是将自动第一布局的xml加入第二个xml里面了
第二种情况:root不为null,attachToRoot为false
如果root不为null,而attachToRoot为false的话,表示不将第一个参数所指定的View添加到root中,然后手动添加进去,效果如下
和第一种一样的效果
我们在开发的过程中给控件所指定的layout_width和layout_height到底是什么意思?该属性的表示一个控件在容器中的大小,就是说这个控件必须在容器中,这个属性才有意义,否则无意义。这就意味着如果我直接将linearlayout加载进来而不给它指定一个父布局,则inflate布局的根节点的layout_width和layout_height属性将会失效(因为这个时候linearlayout将不处于任何容器中,那么它的根节点的宽高自然会失效)。如果我想让linearlayout的根节点有效,又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。这样,指定root的目的也就很明确了,即root会协助linearlayout的根节点生成布局参数,只有这一个作用。
第三种情况:root为null//父布局为传入的为null
当root为null时,不论attachToRoot为true还是为false,显示效果都是一样的
当root为null表示我不需要将第一个参数所指定的布局添加到任何容器中,同时也表示没有任何容器来来协助第一个参数所指定布局的根节点生成布局参数
当第二个参数为null,第三个参数为false时(即使为true显示效果也是一样的,这里以false为例),由于在inflate方法中没有将linearlayout添加到某一个容器中,所以我需要手动添加,另外由于linearlayout并没有处于某一个容器中,所以它的根节点的宽高属性会失效,显示效果如下:
linearlayout的根节点的宽高设置什么,都是没有效果的,它都是包裹button,如果我修改button,则button会立即有变化,因为button是处于某一个容器中的。
测试两个参数
1.root为null—————等于第三种情况
2.root不为null————等于第一种情况
总结
总之一句话,推荐用下边第二种方式:
inflater.inflate(R.layout.item, parent, false);
1如果root为null,无论attachToRoot为true或者false,效果都是一样的
2如果root不为null,attachToRoot为true,表示将layout布局添加到root布局中
3如果root不为null,attachToRoot为false,表示不将layout布局添加到root布局,若要添加则需要手动addView
4如果root不为null,不设置attachToRoot(即调用两个参数的方法),情况和(2)中一样