1. 使用方法
需要先在Module的build.gradle文件的dependencies中添加依赖库constraint-layout:
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.0.0'
//添加constraint-layout依赖库
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
然后就可以在xml文件中使用了。
<?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">
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
android:padding="10dp"
android:text="Hello World!" />
<TextView
android:id="@+id/id_tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ccbbaa"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
android:padding="5dp"
android:text="Hello World!" />
</android.support.constraint.ConstraintLayout>
2. 常见属性
1. layout_constraintX_toXof系列
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_constraintLeft_toRightOf效果一致
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
ConstraintLayout属性的名字都好长,配合着效果再来理解就容易多了。
我的理解方法是分段理解的,
比如 layout_constraintLeft_toLeftOf 这个属性可以分为3段,layout,constraintLeft和toLeftOf,
根据名字来理解,layoutConstraintLayout所有属性都有的字段,可以忽略。终点看后两段:
constraintLeft: 表示当前控件的左边
toLeftOf: 表示当前控件的某一条边在另外一个控件的左边
constraintLeft 和 toLeftOf 配合起来就表示:当前控件的左边在另外一个控件的左边。
ConstraintLayout的所有属性都表示的是一种相对位置的关系
- 居中显示:
根据我们的理解方式,想要居中显示,只需要让控件的左,上,右,下四条边分别在父布局的左,上,右,下即可.
<?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">
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
android:padding="10dp"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
- 让黄色背景的TextView位于蓝色背景TextView的右边
<?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">
<!--居中显示-->
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
android:padding="10dp"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<!--位于id_tv1的右边-->
<TextView
android:id="@+id/id_tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
android:background="#ccbbaa"
android:padding="5dp"
android:text="Hello World!"/>
</android.support.constraint.ConstraintLayout>
- 如果想让两个黄色背景的View和蓝色背景的View水平显示,文字对齐 ,id_tv2 加一条属性即可
<TextView
android:id="@+id/id_tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
android:background="#ccbbaa"
android:padding="5dp"
android:text="Hello World!"/>
2. app:layout_goneMarginX和margin的区别
这系列表示的就是margin值,但是和margin表达的意思不太一样。
1. margin:表示的就是当前控件相对于指定控件的外边距
2. app:layout_goneMarginX:如果当前控件B添加了控件A的约束,控件B设置了goneMarginX属性,那么只有当控件A隐藏的时候goneMarginX的值才会起作用。
如图紫色的TextView添加了土黄色TextView的约束,并且土黄色TextView处于显示状态,而紫色View设置了marginLeft=”10dp” 和 goneMarginLeft=”20dp” ,可以看到只有margin生效了
<?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"
tools:context="com.hank.ok.bottomsheet.MainActivity">
<!--居中显示-->
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
android:padding="10dp"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<!--位于id_tv1的右边-->
<TextView
android:id="@+id/id_tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
android:background="#ccbbaa"
android:padding="5dp"
android:text="Hello World!"/>
<!--添加了layout_goneMarginLeft属性-->
<TextView
android:id="@+id/id_tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
app:layout_goneMarginLeft="20dp"
app:layout_constraintLeft_toRightOf="@id/id_tv2"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
android:background="#bbaccc"
android:padding="5dp"
android:text="Hello World!"/>
</android.support.constraint.ConstraintLayout>
接下来把土黄色View设置为Gone,看下效果
明显可以看出goneMarginLeft生效了。
总结:margin和goneMargin可以同时设置,但是效果不会叠加,goneMargin只有在添加约束的View状态为Gone的时候,才起作用,而此时,margin是没有效果的。
3. layout_constraintHorizontal_bias 偏向
意思就是当前控件更偏向于哪边,值0~1,0表示靠左显示,值越大越靠右
这个属性值只在左右两侧都设置了约束的情况下起作用,否则不起作用
下图是设置了土黄色View的倾向值为0.5的结果,它就在蓝色和紫色View中间显示了,如果改成0.3,它会显示在蓝色和紫色View之间距离的1/3处
代码:
<?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">
<!--居中显示-->
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
android:padding="10dp"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<!--位于id_tv1的右边-->
<TextView
android:id="@+id/id_tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintRight_toLeftOf="@+id/id_tv3"
app:layout_constraintHorizontal_bias="0.5"
android:background="#ccbbaa"
android:padding="5dp"
android:text="Hello World!"/>
<!--添加了layout_goneMarginLeft属性-->
<TextView
android:id="@+id/id_tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
app:layout_constraintHorizontal_bias="0.5"
android:background="#bbaccc"
android:padding="5dp"
android:text="Hello World!"/>
</android.support.constraint.ConstraintLayout>
4. layout_constraintDimensionRatio 宽高比
用来设置控件的宽高比例
设置宽高3:1
<TextView
android:id="@+id/id_tv2"
android:layout_width="0dp"
android:layout_height="30dp"
app:layout_constraintBaseline_toBaselineOf="@id/id_tv1"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintRight_toLeftOf="@+id/id_tv3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintDimensionRatio="3:1"
android:background="#ccbbaa"
android:padding="5dp"
android:text="Hello World!"/>
5. Chain 链式
Chains提供在一个轴(横向或纵向)类似group的行为。其他轴可以独立约束
更详细的可以看 http://blog.csdn.net/zxt0601/article/details/72683379
创建一个链
如果一组组件通过双向连接连接在一起,我们就可以认为是他们是一个链,(如下图,显示最小链,由两个组件组成)。
链头 Chain heads
链是由属性集合的第一个元素控制(链的“头”):
链的样式
当链的第一个元素设置属性layout_constraintHorizontal_chainStyle 或layout_constraintVertical_chainStyle,链的行为会根据指定的样式改变(默认为CHAIN_SPREAD)。
CHAIN_SPREAD – 元素会被展开 (默认)
Weighted chain – 在CHAIN_SPREAD模式中,如果有些组件设置为MATCH_CONSTRAINT,他们将分开可用空间
CHAIN_SPREAD_INSIDE – 相似,但链的端点不会散开
CHAIN_PACKED – 链的元素将被打包在一起。子元素水平或垂直偏移(bias)属性将影响元素的定位
权重链
链的默认行为是元素伸展相同的可用空间。
如果一个或多个元素使用MATCH_CONSTRAINT,他们将利用剩余的空间(等分)。
属性layout_constraintHorizontal_weight,
layout_constraintVertical_weight将控制分布在空间的元素如何使用MATCH_CONSTRAINT。
例如,使用MATCH_CONSTRAINT链包含两个元素,
第一个元素使用的权重2,
第二个元素使用权重1,
占用的空间第一个元素将是第二个元素的两倍。
下边是一个双项链
土黄色View和紫色View的宽度layout_width=”0dp”,也就是match_contraint,
链头的 app:layout_constraintHorizontal_chainStyle=”spread”
效果如下图:
土黄色和紫色View根据权重沾满了剩下的空间
<?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">
<!--居中显示-->
<TextView
android:id="@+id/id_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aabbcc"
app:layout_constraintRight_toLeftOf="@+id/id_tv2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="0.5"
android:padding="10dp"
android:text="Hello World!"/>
<!--位于id_tv1的右边-->
<TextView
android:id="@+id/id_tv2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_weight="0.5"
android:background="#ccbbaa"
android:padding="5dp"
app:layout_constraintLeft_toRightOf="@id/id_tv1"
app:layout_constraintRight_toLeftOf="@+id/id_tv3"
android:text="Hello World!"/>
<!--添加了layout_goneMarginLeft属性-->
<TextView
android:id="@+id/id_tv3"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/id_tv2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_weight="0.5"
android:background="#bbaccc"
android:padding="5dp"
android:text="Hello World!"/>
</android.support.constraint.ConstraintLayout>