Merge标签用作布局中减少冗余的节点.
通过代码来解释.
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include layout="@layout/content" />
</LinearLayout>
content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
得到的效果如下.
查看hierarchyviewer(在你的sdk目录 XXX\sdk\tools里面hierarchyviewer.bat)
红方框里面就是三个Button, include进来的两个Button前面多了一层LinerLayout
这层LinerLayout作为被包含的视图的根元素, 和父级结构中的LinerLayout一致, 是一个冗余的节点. 可以通过Merge标签来减少一个层级.
修改为
content_merge.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</merge>
再次查看hierarchyviewer
红方框里面是三个Button, 比上面的少了一层LinerLayout
网上有老司机提到
只可以作为xml layout的根节点。
当需要扩充的xml layout本身是由merge作为根节点的话,需要将被导入的xml layout置于
viewGroup中,同时需要设置attachToRoot为True。
第二点老司机们并没有解释一下
LayoutInflater中有这个方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
还是用代码来解释
MainActivity.java
public class MainActivity extends AppCompatActivity {
private FrameLayout mContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContainer = (FrameLayout) findViewById(R.id.container);
getLayoutInflater().inflate(R.layout.content_merge, mContainer, false);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
content_merge.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="content_merge" />
</merge>
“`
getLayoutInflater().inflate(R.layout.content_merge, mContainer, false);
运行到这句, 抛出异常:
Caused by: android.view.InflateException: Binary XML file line #2:< merge /> can be used only with a valid ViewGroup root and
attachToRoot=true
Caused by: android.view.InflateException: < merge /> can be used only with a valid ViewGroup root and attachToRoot=true
改成
getLayoutInflater().inflate(R.layout.content_merge, mContainer, true);
就能正常显示了