1 使用constraintLayout原因
在开发过程中遇到一些复杂的UI,可能会出现嵌套过多的问题,嵌套的越多,设备视图所需的时间和计算功耗就越多;它同时支持LinearLayout与RelativeLayout的所用特性。同时它完全通过约束来减少布局的嵌套。意思就是基本上最外层只需要一个ConstraintLayout节点就可以了;
2 如何使用constraintLayout
首先我们需要在app/build.gradle文件中添加ConstraintLayout的依赖
implementation 'com.android.support.constraint:constraint-layout:1.1.3’
3 相对定位
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
当两个TextView的高度不一致,但是又希望他们文本对齐,这个时候就可以使用layout_constraintBaseline_toBaselineOf
<TextView
android:id="@+id/TextView1"
.../>
<TextView
android:id="@+id/TextView2"
...
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>
4 角度定位
角度定位指的是可以用一个角度和一个距离来约束两个空间的中心
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintCircle="@+id/TextView1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="150dp" />
5 边距Margin
android:layout_marginStart
android:layout_marginEnd
android:layout_marginLeft
android:layout_marginTop
android:layout_marginRight
android:layout_marginBottom
如果要使margin生效,需要设置对应边的约束。但如果宽为match_parent,则相当于有了左右(left、right、start、end)两边的约束,左右都和父布局(constraintLayout)对齐,这是就不用再显示的设置两个边的约束了。
6 goneMargin
app:layout_goneMarginStart
app:layout_goneMarginEnd
app:layout_goneMarginLeft
app:layout_goneMarginTop
app:layout_goneMarginRight
app:layout_goneMarginBottom
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/TextView1"
.../>
<TextView
android:id="@+id/TextView2"
...
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_goneMarginLeft="10dp"
/>
</android.support.constraint.ConstraintLayout>
7 居中和偏移
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
ConstraintLayout还提供了另外一种偏移的属性:
layout_constraintHorizontal_bias 水平偏移
layout_constraintVertical_bias 垂直偏移
<TextView
android:id="@+id/TextView1"
...
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
8 宽高比
app:layout_constraintDimensionRatio
宽高比,该属性生效的条件是至少宽或高其中一个属性为 0dp,它的属性值设置为下面三种形式:
9 链
<android.support.constraint.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">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="java"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/button2"
app:layout_constraintHorizontal_chainStyle="spread"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android"
app:layout_constraintRight_toLeftOf="@id/button3"
app:layout_constraintLeft_toRightOf="@id/button1"/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/button2"/>
</android.support.constraint.ConstraintLayout>
当在链的第一个元素(head)上设置属性layout_constraintHorizontal_chainStyle或layout_constraintVertical_chainStyle时,链的行为将根据指定的样式更改(默认是CHAIN_SPREAD)。
-
spread :默认,除去margin,剩余空间(不包含已设置的margin)平均分配到每个view的两边
-
spread_inside:类似,但是链的两端不分配剩余空间
-
Weighted chain:不是属性,而是当设置为上面两个属性时,链中的view如果宽度为0(垂直链则是高度为0),则这些view平分剩余空间作为自己的宽高。layout_constraintHorizontal_weight和layout_constraintVertical_weight属性将控制如何使用MATCH_CONSTRAINT在元素之间分配空间。例如其中有两个view的宽或高为0,第一个元素使用权重2,第二个元素使用权重1,第一个元素占用的空间将是第二个元素占用的空间的两倍。
-
packed:链的元素会被打包在一起居中显示。
-
Packed Chain with Bias:不是属性,而是设置为packed时,水平或垂直bias属性将影响包装元素的位置。app:layout_constraintHorizontal_bias app:layout_constraintVertical_bias就是这两个属性,也是在链的head上设置。
10 辅助元素
1 GuildLine
<android.support.constraint.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">
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
app:layout_constraintGuide_begin="100dp"
android:orientation="vertical"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
app:layout_constraintLeft_toLeftOf="@+id/guideline"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
位置通过app:layout_constraintGuide_begin距离开始位置 layout_constraintGuide_end距离结束位置 layout_constraintGuide_percent距离开始位置百分比,浮点数,如0.5来设置
2 Barrier
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="java"
app:layout_constraintTop_toBottomOf="@id/place"/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="androidddddddd"
app:layout_constraintTop_toBottomOf="@id/button1"
/>
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="100p"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="button1,button2"/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="hello"
app:layout_constraintLeft_toRightOf="@id/barrier"/>
</android.support.constraint.ConstraintLayout>
3 Group
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="button4,button9" />
同时控制多个view的显示和隐藏,app:constraint_referenced_ids控制多个view的id,用,分割;android:visibility控制显示隐藏。本身不会显示,不占用空间,设置其他宽高也无效。多个Group可同时控制一个view,以Group在xml中布局顺序决定最终的显示隐藏。
4 Placeholder
<android.support.constraint.Placeholder
android:layout_width="100dp"
android:layout_height="100dp"
app:content="@id/button2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"/>
占位,当设置content时,contentid所代表的view就会消失不见,而在Placeholder中显示,此时Placeholder的宽高设置无效,最终的宽高是contentid所代表的view的宽高。也可以通过代码setContentId(int id)设置。