ConstraintLayout約束布局
Google大力推廣布局方式。
高性能:基本一層布局搞定谓着,不用嵌套多層布局
功能強大:百分比布局、設(shè)置自身寬高比例,各種輔助組件
可拖拽編輯:和ios拖拽布局很相似
缺點:用了約束布局后谊路,再也無法回到以前的布局方式了,重度依賴
基本布局方式
app:layout_constraintStart_toStartOf -->自身左邊與目標(biāo)左邊對齊
偏移量bias
居中顯示菩彬,要往左邊靠一點。可以通過bias來實現(xiàn)
app:layout_constraintHorizontal_bias-->水平方向的偏移客税,取值[0f,1.0f](0為靠向最左邊系草,1為靠到最右邊)
margin
margin生效,必須同一方向上的約束耙旦,要marginBottom就必須layout_constraintBottom_toxxxof
goneMargin(隱藏邊距)
-layout_goneMarginStart
-layout_goneMarginEnd
-layout_goneMarginLeft
-layout_goneMarginTop
-layout_goneMarginRight
-layout_goneMarginBottom
大小設(shè)置
約束布局下三種大小設(shè)置模式
spread, wrap,percent脱羡;
app:layout_constraintWith_default-->設(shè)置
注意:使用約束布局的大小設(shè)置,需要先將要設(shè)置的寬或高指定0dp
spread:默認
表示在約束條件下的最大尺寸
wrap模式
自適應(yīng)大小免都,不會超過約束條件下的最大尺寸
傳統(tǒng)的wrap_content模式,約束布局有額外的屬性,使得它也能保留約束條件
android:layout_width="0dp"http:// 對應(yīng)比例的地方為0
app:layout_constrainedWidth="true"此時與wrap模式一樣的效果
###percent模式
以父布局的百分比作為自身大小轻黑,通過layout_constraintWith_percent設(shè)置比例大小[0f,1.0f]
指定寬高比ratio
使其生效必須設(shè)置寬或高為0dp
app:layout_constraintDimensionRatio-->指定view自身的寬高比例。
如果寬高兩項為0dp的話琴昆,則最終尺寸設(shè)置符合約束的最大尺寸氓鄙,同時保持設(shè)置的比例。有時候不是我們想要的业舍,可以指定寬或者高(H,W)哪一邊約束條件來確定尺寸抖拦。
app:layout_constraintDimensionRatio="W,2:1"-->寬對按照比例計算最終尺寸。
app:layout_constraintDimensionRatio="H,2:1"-->則相反
最大和最小值(max/min)
app:layout_constraintHeight_min
鏈布局(chain)
可以快速實現(xiàn)等分布局舷暮,還可以實現(xiàn)類似LinearLayout布局的weight比重功能态罪。
約束鏈三種模式:
spread:view之間均勻分布(默認)
spread_inside:除了約束鏈的頭部和尾部貼在兩邊,其余均勻分布
packed:所有view緊貼在一起,默認居中
注意:layout_constraintLeft_toLeftOf(正常)和layout_constraintStart_toStartOf(不正常)在布局表現(xiàn)不一樣下面;以此類推
在鏈上設(shè)置權(quán)重
app:layout_constraintHorizontal_weight--->權(quán)重
圓形布局
app:layout_constraintCircle-->圓心复颈,某個view的id
app:layout_constraintCircleRadius-->半徑
app:layout_constraintCircleAngle-->角度,值[0,360]沥割,0是正上方
button2在button1正上方(半徑100dp)向右偏移45度
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button ONE"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintCircle="@+id/button1"
app:layout_constraintCircleRadius="100dp"
app:layout_constraintCircleAngle="45"
android:text="Button TWO"/>
</android.support.constraint.ConstraintLayout>
bt2在bt1右下側(cè)
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constrainedWidth="false"
android:text="button one"/>
<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/bt1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bt1"
android:text="Button TWO"/>
</android.support.constraint.ConstraintLayout>
app:layout_constrainedWidth="false" 時候隨著bt2內(nèi)容的增多耗啦,bt2橫向變寬當(dāng)寬度達到最大時,自動換行縱向變高机杜,bt2會擴展到bt1中心位置下方帜讲,bt2屏幕右側(cè)會覆蓋一部分內(nèi)容。
app:layout_constrainedWidth="true" bt2會擴展到bt1右側(cè)位置下方椒拗,屏幕右側(cè)不會覆蓋一部分內(nèi)容似将。
輔助組件
Group:控制可見
Guideline:輔助線
Barrier:邊界范圍
Group控制可見性
Group虛擬視圖获黔,通過constraint_refrenfed_ids放置里面,統(tǒng)一同時控制這些view的課件性在验。
<androidx.constraintlayout.widget.Group
android:id="@+id/mGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="img1,img2"
/>
// 代碼中控制可見性
mGroup.visibility = View.VISIBLE
輔助線
Guideline虛擬輔助線玷氏,水平、垂直腋舌,幫助定位预茄。
兩個view在屏幕中間一左一右,可以通過在屏幕中間放置一個虛擬輔助線侦厚,兩個view分布約束到輔助線的兩側(cè)耻陕。
android:orientation-->設(shè)置垂直還是水平
app:layout_constraintGuide_percent-->通過百分比設(shè)置位置,取值[0f,1.0f]或者[0%,100%]
app:layout_constraintGuide_begin-->設(shè)置相對start/top的偏移量刨沦,dp
app:layout_constraintGuide_end-->設(shè)置相對end/bottom的偏移量诗宣,dp
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
/>
<ImageView
android:id="@+id/img1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img1"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline"
android:layout_marginTop="20dp"
android:layout_marginEnd="50dp"
/>
<ImageView
android:id="@+id/img2"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img2"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/guideline"
android:layout_marginTop="20dp"
android:layout_marginStart="50dp"
/>
Barrier:獲取邊界范圍
Barrier可以獲取多個約束view的邊界,可以獲得所包含的多個view的最左最右等邊界想诅。
左邊是text1和text2召庞,另外一個view必須放在這兩個text的右邊。barrier可以動態(tài)獲取右側(cè)来破。解決問題
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text1,text2"
app:barrierDirection="end"
/>
<ImageView
android:id="@+id/img1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img1"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="@id/text1"
app:layout_constraintBottom_toBottomOf="@id/text2"
app:layout_constraintStart_toEndOf="@id/barrier"
android:layout_marginStart="50dp"
/>
技巧 寬度限制layout_width="0dp"(高度上同理)
場景1:設(shè)置view2的寬度和view1的寬度一樣篮灼。設(shè)置view2為
android:layout_width="0dp"
layout_constraintStart_toStartOf=view1;
layout_constraintEnd_toEndOf=view1;
場景2:設(shè)置百分比寬為0.7:
android:layout_width="0dp"
layout_constraintWidth_percent="0.7"
merge 在ConstraintLayout使用
主布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<TextView
android:id="@+id/tvTest1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="50dp"
android:text="測試布局"
android:textSize="26sp"
/>
<include layout="@layout/include_test"/>
</androidx.constraintlayout.widget.ConstraintLayout>
次布局:include_test.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<TextView
android:id="@+id/tvTest2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/tvTest1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="測試布局"
android:textSize="26sp"
/>
</merge>
注意:
主布局的include不需要加id和寬高限制。
次布局include中的merge不需要寬高限制徘禁。需要添加tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"約束诅诱,方便在xml預(yù)覽主視圖。
merge中的布局可以直接引用主視圖的布局進行位置定位送朱。