当前位置: 代码迷 >> 综合 >> LayoutInflater.inflate()方法的深入理解
  详细解决方案

LayoutInflater.inflate()方法的深入理解

热度:20   发布时间:2024-02-01 15:43:15.0

LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)

方法有一个接收三个参数的方法重载 resource:R.layout.xxx ,root:指定resource的父布局 ,attachToRoot:是否依附于父布局。
inflate(int resource, ViewGroup root, boolean attachToRoot)

  • 看源码可知:
  1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。
  2. 如果root不为null,attachToRoot设为true,则会给加载resource的布局文件的指定一个父布局,即root。
  3. 如果root不为null,attachToRoot设为false,则会将布局文件外层viewGroup的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。(layoutparams)
  4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

列子如下:

  • 先写一个activity_main.xml,这个布局文件很简单,只有一个空的LinearLayout。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/main_layout"android:layout_width="match_parent"android:layout_height="match_parent" >
</LinearLayout>
  • 再写一个button_layout_1.xml,这个布局我们加入一个Button按钮,宽高固定,并且外层没有父Layout。
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="200dp"android:layout_height="50dp"android:text="Button">
</Button>
  • 再写一个button_layout_1.xml,这个布局我们加入一个Button按钮,宽高固定,并且外层没有父Layout。
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="200dp"android:layout_height="50dp"android:text="Button">
</Button>
  • 最后写一个button_layout_2.xml,加入Button按钮,外层嵌套一个父Layout,父Layout的宽高固定。

方法1. 如果我们用以下代码来解析button_layout_1,那么中Button所设置的宽高是不生效的。

ViewGroup mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View buttonLayout = LayoutInflater.from(this).inflate(R.layout.button_layout_1, null);
mainLayout.addView(buttonLayout);

方法2. 而如果我们设置了inflate方法的root参数,并且attachToRoot设为true,那么Button所设置的宽高就生效了。

ViewGroup mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View buttonLayout = LayoutInflater.from(this).inflate(R.layout.button_layout_1, mainLayout, true);
// 不需要再addView
// mainLayout.addView(buttonLayout);

这是为什么呢?

首先,layout_width和layout_height 其实是用于设置View在布局中的大小的,也就是说,View必须存在于一个布局中,之后如果将layout_width、layout_height 设置成match_parent 或 wrap_content 或 固定的数值才会生效,这也是为什么这两个属性叫作layout_width和layout_height,而不是width和height

方法1中root设为null,Button外层又没有父Layout,所以Button所设置的宽高并没有生效

方法2中root设为mainLayout,attachToRoot设为true,会给加载的布局文件的指定一个父布局,所以Button的宽高就生效了,这也就对应了最上边的结论2

那么我们再来看button_layout_2

  • 方法1. 设置root为null,Button的父布局RelativeLayout设置的宽高就无效
ViewGroup mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View buttonLayout = LayoutInflater.from(this).inflate(R.layout.button_layout_2, null);
mainLayout.addView(buttonLayout);
  • 方法2. 设置root设为mainLayout,attachToRoot设为false,Button的父布局RelativeLayout设置的宽高就生效了
ViewGroup mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View buttonLayout = LayoutInflater.from(this).inflate(R.layout.button_layout_2, mainLayout, false);
mainLayout.addView(buttonLayout);

这也就对应了最上边的结论3:如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。