Android ConstraintLayout 佈局
AndroidStudio 3.0 預設ConstraintLayout,可以減少佈局層級並提高佈局效能;能夠靈活的定位和調整子View的大小,子View依靠約束關係來確定位置。
一、基本屬性
屬性 | 作用 |
---|---|
layout_constraintLeft_toLeftOf |
左邊左對齊 |
layout_constraintLeft_toRightOf |
左邊右對齊 |
layout_constraintRight_toLeftOf |
右邊左對齊 |
layout_constraintRight_toRightOf |
右邊右對齊 |
layout_constraintTop_toTopOf |
上邊頂部對齊 |
layout_constraintTop_toBottomOf |
上邊底部對齊 |
layout_constraintBottom_toTopOf |
下邊頂部對齊 |
layout_constraintBottom_toBottomOf |
下邊底部對齊 |
layout_constraintBaseline_toBaselineOf |
文字內容基準線對齊 |
layout_constraintStart_toEndOf |
起始邊向尾部對齊 |
layout_constraintStart_toStartOf |
起始邊向起始邊對齊 |
layout_constraintEnd_toStartOf |
尾部向起始邊對齊 |
layout_constraintEnd_toEndOf |
尾部向尾部對齊 |
這些屬性為控制元件添加了某個方向的約束力,根據某個方向約束力的“有無”和“強弱”,空間會位於不同的位置
<?xml version="1.0" encoding="utf-8"?> <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"> <TextView android:id="@+id/tv1" android:background="@color/colorPrimary" android:layout_width="100dp" android:layout_height="100dp" android:text="tv1" android:gravity="center" android:textSize="20pt" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/> <TextView android:id="@+id/tv2" android:background="@color/colorPrimary" android:layout_width="100dp" android:layout_height="100dp" android:text="tv2" android:gravity="center" android:textSize="20pt" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/tv1" app:layout_constraintTop_toBottomOf="@+id/tv1"/> <TextView android:id="@+id/tv3" android:background="@color/colorPrimary" android:layout_width="100dp" android:layout_height="100dp" android:text="tv3" android:gravity="center" android:textSize="20pt" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/tv2" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv2"/> </android.support.constraint.ConstraintLayout>
tv1設定了上、左的約束 tv2設定了左、上、下的約束,有上下居中的效果 tv3設定了上、下、左、右的約束,有居中的效果
二、偏移量
屬性 | 作用 |
---|---|
layout_constraintHorizontal_bias |
水平方向偏移量 |
layout_constraintVertical_bias |
垂直方向偏移量 |
<?xml version="1.0" encoding="utf-8"?>
<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">
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="tv1"
android:gravity="center"
android:textSize="20pt"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
tv1設定了居中
<?xml version="1.0" encoding="utf-8"?>
<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">
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="tv1"
android:gravity="center"
android:textSize="20pt"
app:layout_constraintVertical_bias="1"
app:layout_constraintHorizontal_bias="0.8"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
設定它的垂直偏移量為1,水平偏移量為0.8
三、Visibility 屬性
如果View的屬性Visibility設定為gone,那麼原本依賴它來參照定位的屬性就會失效,ConstraintLayout佈局會有所不同
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
<?xml version="1.0" encoding="utf-8"?>
<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">
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="tv1"
android:gravity="center"
android:textSize="20pt"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tv2"
android:background="@color/colorPrimary"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="tv2"
android:gravity="center"
android:textSize="20pt"
app:layout_goneMarginTop="100dp"
app:layout_constraintLeft_toRightOf="@+id/tv1"
app:layout_constraintTop_toBottomOf="@+id/tv1"/>
</android.support.constraint.ConstraintLayout>
當tv1的Visibility 屬性設定為gone時,tv1縮小為一個不可見的點,位於原先位置的左上角,屬性app:layout_goneMarginTop="100dp"
就會生效,tv2移到新的位置
四、寬高比
其他佈局中要實現View的寬高比會比較麻煩,ConstraintLayout中可以直接實現:
- 將View的寬高設定為0dp
- 設定
app:layout_constraintDimensionRatio
屬性
<?xml version="1.0" encoding="utf-8"?>
<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">
<ImageView
android:id="@+id/iv1"
android:background="@color/colorPrimary"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
還支援這樣的寫法
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintDimensionRatio="W,9:16"
五、控制元件權重
ConstraintLayout 可以像LinearLayout 一樣為之控制元件設定layout_weight
屬性,從而控制子控制元件之間的佔比
<?xml version="1.0" encoding="utf-8"?>
<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">
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="0dp"
android:layout_height="50dp"
android:gravity="center"
android:text="text1"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintRight_toLeftOf="@id/tv2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tv2"
android:background="@color/colorAccent"
android:layout_width="0dp"
android:layout_height="50dp"
android:gravity="center"
android:text="text2"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/tv1"
app:layout_constraintRight_toLeftOf="@id/tv3"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tv3"
android:background="@color/colorPrimaryDark"
android:layout_width="0dp"
android:layout_height="50dp"
android:gravity="center"
android:text="text3"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/tv2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
橫向相當於一個鏈(Chains),在鏈的最左邊的元素成為鏈頭,還可以給它設定一些屬性(layout_constraintHorizontal_chainStyle
),來展示更多的效果
- 當wight不等於零
app:layout_constraintHorizontal_chainStyle="spread"
(預設)app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_chainStyle="spread_inside"
六、錨向指示線
其實指示線(Guideline)是來幫助定位的,不會出現在實際介面中,它有幾個特性:
- 寬度和高度都是0
- 可見性為View.GONE
- 通過
orientation
設定方向
<?xml version="1.0" encoding="utf-8"?>
<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">
<android.support.constraint.Guideline
android:id="@+id/gl1"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<android.support.constraint.Guideline
android:id="@+id/gl2"
app:layout_constraintGuide_begin="100dp"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv1"
android:background="@color/colorPrimary"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="tv1"
android:gravity="center"
android:textSize="20pt"
app:layout_constraintLeft_toLeftOf="@id/gl1"
app:layout_constraintTop_toTopOf="@id/gl2"/>
</android.support.constraint.ConstraintLayout>
設定橫向指示線距離頂部 100dp 豎向指示線設定其距離百分比為 0.5