Android布局優(yōu)化:include 、merge、ViewStub詳細總結(jié)
1.include的用法
- include.xml
<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"
android:background="@android:color/white"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="100dp"
android:layout_marginRight="20dp"
android:hint="請輸入用戶名" />
<include layout="@layout/include_login" />
</LinearLayout>
- include_login.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="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="登錄按鈕" />
</LinearLayout>
層級關(guān)系如下圖:

image.png
2.merge的用法
include標簽存在著一個不好的地方,可能會導(dǎo)致產(chǎn)生多余的布局嵌套。merge標簽存在的意義就是幫助include標簽排除多余的一層ViewGroup容器,減少View的層級結(jié)構(gòu),提升UI渲染的性能。
- merge.xml
<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"
android:orientation="vertical"
android:background="@android:color/white">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="100dp"
android:hint="請輸入用戶名" />
<include layout="@layout/merge_login" />
</LinearLayout>
- merge_login.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:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="登錄按鈕" />
</merge>
使用merge標簽優(yōu)化后的層級關(guān)系如下圖:

image.png
注意:根布局是FrameLayout且不需要設(shè)置background或padding等屬性時,可以用merge代替,因為Activity的contentView父元素就是FrameLayout,所以可以用merge消除。
3.ViewStub用法
ViewStub也可以用來加載布局文件,但與include標簽完全不同。ViewStub是一個不可見的View類,用于在運行時按需懶加載資源,只有在代碼中調(diào)用了viewStub.inflate()或者viewStub.setVisible(View.visible)方法時才內(nèi)容才變得可見.
- view_stub.xml
<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"
android:background="@android:color/white"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="40dp"
android:hint="請輸入用戶名" />
<ViewStub
android:id="@+id/viewstub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/view_stub_info" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="showViewStub"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:text="顯示" />
</LinearLayout>
- view_stub_info.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content" >
<EditText
android:id="@+id/weichat_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:hint="請輸入微信號" />
<EditText
android:id="@+id/address_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:hint="請輸入家庭住址" />
</LinearLayout>
- showViewStub()方法顯示ViewStub
public void showViewStub(){
ViewStub stub = ((ViewStub) findViewById(R.id.viewstub));
if(stub!=null){
View stubView=stub.inflate();
EditText address = (EditText) stubView.findViewById(R.id.address_id);
EditText wechatId = (EditText) stubView.findViewById(R.id.weichat_id);
}
}
三.ConstraintLayout
1.基線布局

image.png
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:textSize="50sp"
android:textStyle="bold"
android:text="20"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textSize="25sp"
app:layout_constraintLeft_toRightOf="@id/tv_1"
app:layout_constraintBaseline_toBaselineOf="@id/tv_1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2.角度約束
- layout_constraintCircle 指定一個視圖作為圓形約束的中心點
- layout_constraintCircleRadius 中心點到視圖的距離【約束半徑】
- layout_constraintCircleAngle 約束角度

image.png

image.png
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_android"
android:layout_width="180dp"
android:layout_height="180dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<ImageView
android:id="@+id/jetpack"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@mipmap/demo_device_android"
android:background="@color/btn_pressed_green_solid"
app:layout_constraintCircle="@+id/iv_android"
app:layout_constraintCircleRadius="90dp"
app:layout_constraintCircleAngle="45"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.紅包樹
- layout_constraintVertical_bias 控制視圖在豎直方向上的偏移量(0.0--1.0之間),必須保證視圖在豎直方向上居中,才能使用該屬性.
0.0 靠近頂部約束
0.5 豎直居中
1.0 靠近底部約束
//豎直居中
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
- layout_constraintHorizontal_bias 控制視圖在水平方向上的偏移量(0.0--1.0之間),必須保證視圖在水平方向上居中,才能使用該屬性.
0.0 靠近左邊約束
0.5 水平居中
1.0 靠近右邊約束
//水平居中
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

image.png
示例
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--背景底圖-->
<ImageView
android:id="@+id/treebg"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="@mipmap/ic_tree_bg_daytime"/>
<!--黃金樹-->
<ImageView
android:id="@+id/treeIv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_tree_6"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintVertical_bias="0.40" />
<!--相對于黃金樹,水平偏移0.10,豎直便宜0.26-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_red_packet_9"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
app:layout_constraintHorizontal_bias="0.10"
app:layout_constraintVertical_bias="0.26" />
<!--相對于黃金樹,水平偏移0.10,豎直便宜0.49-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintHorizontal_bias="0.10"
app:layout_constraintVertical_bias="0.49"
/>
<!--相對于黃金樹,水平方向偏移0.28,豎直方向偏移0.15-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintHorizontal_bias="0.28"
app:layout_constraintVertical_bias="0.15"/>
<!--相對于黃金樹,水平方向偏移0.34,豎直方向偏移0.44-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintHorizontal_bias="0.34"
app:layout_constraintVertical_bias="0.44"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintVertical_bias="0.11"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
app:layout_constraintHorizontal_bias="0.52"
app:layout_constraintVertical_bias="0.42"
android:background="@mipmap/ic_red_packet_9"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintHorizontal_bias="0.8"
app:layout_constraintVertical_bias="0.14"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_red_packet_9"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintHorizontal_bias="0.76"
app:layout_constraintVertical_bias="0.51" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/treeIv"
app:layout_constraintBottom_toBottomOf="@id/treeIv"
app:layout_constraintLeft_toLeftOf="@id/treeIv"
app:layout_constraintRight_toRightOf="@id/treeIv"
app:layout_constraintHorizontal_bias="0.95"
app:layout_constraintVertical_bias="0.38"
android:background="@mipmap/ic_red_packet_9" />
</androidx.constraintlayout.widget.ConstraintLayout>