ConstraintLayout简单的基础使用
不管三七二十一,来张官方的截图
官方链接:https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout
yhx.png
官方文档说的很清楚了:ConstraintLayout是个ViewGroup,可以灵活的方式定位和调整
,这句话很重要。
1.ConstraintLayout能够解决什么问题?
一句话加一说明:解决在开发过程中布局过多嵌套问题。
2.如何使用ConstraintLayout?
从androidstudio2.3起,官方模板默认就已经使用了ConstraintLayout,如果还有老铁默认不是ConstraintLayout,那就赶紧升级as吧。怪我咯!!!!!!
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
app:layout_constraintLeft_toRightOf 在目标元素的右侧
<TextView
android:id="@+id/TextView1"
android:layout_width="140dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView1" />
<TextView
android:id="@+id/TextView2"
android:layout_width="140dp"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toRightOf="@id/TextView1" />
yhx.png
app:layout_constraintTop_toBottomOf 在目标元素下方
<TextView
android:id="@+id/TextView2"
android:layout_width="140dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView2"
/>
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/TextView2" />
yhx.png
app:layout_constraintLeft_toLeftOf="parent" 在父元素左边
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:text="TextView2"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
/>
yhx.png
app:layout_constraintRight_toRightOf="parent" 在父元素右边
<TextView
android:id="@+id/TextView3"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:text="TextView2"
android:gravity="center"
app:layout_constraintRight_toRightOf="parent"
/>
yhx.png
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"同时使用
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
yhx.png
app:layout_constraintBaseline_toBaselineOf 文本对齐
TextView1高度为150dp
TextView2高度50dp
如果不设置app:layout_constraintBaseline_toBaselineOf 应该是这样显示的
yhx.png
设置app:layout_constraintBaseline_toBaselineOf 之后显示是这样的 ,使文本对齐了
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="100dp"
android:background="@color/colorPrimaryDark"
android:text="TextView2"
android:gravity="center" />
<TextView
android:id="@+id/TextView2"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:text="TextView2"
android:layout_marginLeft="20dp"
android:gravity="center"
app:layout_constraintLeft_toRightOf="@id/TextView1"
app:layout_constraintBaseline_toBaselineOf="@id/TextView1"
/>
yhx.png
角度定位
概念:就是用一个角度,和距离来约束两个物理的位置。
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="80dp"
android:background="@color/colorPrimaryDark"
android:text="TextView1"
android:gravity="center" />
<TextView
android:id="@+id/TextView2"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:text="TextView2"
android:layout_marginLeft="20dp"
android:gravity="center"
app:layout_constraintCircle="@id/TextView1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="180dp"
/>
app:layout_constraintCircle 目标位置
app:layout_constraintCircleAngle="120" 角度
app:layout_constraintCircleRadius="180dp" 距离
翻译过来就是:TextView2的中心位置在TextView1中心120度,距离为150dp处
yhx.png边距 margin
ConstraintLayout的边距常用属性如下:
- android:layout_marginStart
- android:layout_marginEnd
- android:layout_marginLeft
- android:layout_marginTop
- android:layout_marginRight
- android:layout_marginBottom
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="TextView2"
/>
</android.support.constraint.ConstraintLayout>
yhx.png
发现我设置了android:layout_marginLeft="20dp" android:layout_marginTop="20dp"竟然没有效果, 在ConstraintLayout 里面要实现margin ,必须先约束该控件在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"
tools:context=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
特别注意: 1。直接给TextView1 设置 android:layout_marginLeft="20dp" 和 android:layout_marginTop="20dp" 单独在ConstraintLayout里面不生效的。 2。必须要给TextView1 约束一个相对位置。
goneMargin的使用
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值,属性如下:
- layout_goneMarginStart
- layout_goneMarginEnd
- layout_goneMarginLeft
- layout_goneMarginTop
- layout_goneMarginRight
- layout_goneMarginBottom
layout_goneMarginLeft 举例说明
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="TextView2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView2"
app:layout_goneMarginLeft="20dp"
app:layout_constraintLeft_toRightOf="@id/TextView1" />
</android.support.constraint.ConstraintLayout>
当我把TextView2 设置 app:layout_goneMarginLeft="20dp" ,把TextView1 分别 设置android:visibility="gone",和TextView1 设置 android:visibility="visible" 前后对比效果
yhx.png当我把TextView1设置gone时,TextView2的app:layout_goneMarginLeft="20dp"就生效了
居中和偏移
在RelativeLayout,常用 android:layout_centerHorizontal="true" android:layout_centerVertical="true",使控件在父布局中水平居中,或者垂直居中。
在ConstraintLayout 使用
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
水平居中.png
当把TextView1 设置为水平时,还可以设置android:layout_marginLeft="30dp"
水平居中并且设置margin之后.png当把TextView1设置属性app:layout_constraintHorizontal_bias="0.3"时
水平居中并且设置app:layout_constraintHorizontal_bias之后.png
注意:app:layout_constraintHorizontal_bias 取值范围为0-1,为0时,显示在布局最左侧,为1时,显示在布局最右侧,为0.5时,居中显示
app:layout_constraintVertical_bias=""同理可证,忽略了,约束的方向则变成了上和下即可。
尺寸约束
官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_marginLeft="60dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
TextView1宽度设为0dp,左右两边约束parent的左右两边,并设置左边边距为60dp
yhx.png设置宽高比
当宽或高至少有一个尺寸被设置为0dp时,可以通过属性
layout_constraintDimensionRatio来设置宽高比
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintDimensionRatio="1:1"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toLeftOf="parent"
/>
</android.support.constraint.ConstraintLayout>
yhx.png
注意:app:layout_constraintDimensionRatio不能单独使用 ,需要给该控件约束位置,例如给该控制设置app:layout_constraintLeft_toLeftOf="parent" 配合 app:layout_constraintDimensionRatio="1:1" 才有效果
链
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/TextView2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView2"
app:layout_constraintLeft_toRightOf="@id/TextView1"
app:layout_constraintRight_toLeftOf="@id/TextView3" />
<TextView
android:id="@+id/TextView3"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView3"
app:layout_constraintLeft_toRightOf="@id/TextView2"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
3个TextView相互约束,两端两个TextView分别与parent约束,成为一条链
yhx.png看这效果图:就是等分啊
一条链的第一个控件是这条链的链头,我们可以在链头中设置
layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是:
spread—— 展开元素 (默认);
spread_inside—— 展开元素,链的两端贴近parent;
packed—— 链的元素将被打包在一起。
如图所示:
当把3个TextView 的layout_width 设置为0dp时
yhx.png
当把layout_width 设置为0dp时,配合layout_constraintHorizontal_weight(constraintVertical为纵向)使用,又就是权重链
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:gravity="center"
android:text="TextView1"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/TextView2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="TextView2"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintLeft_toRightOf="@id/TextView1"
app:layout_constraintRight_toLeftOf="@id/TextView3" />
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="TextView3"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintLeft_toRightOf="@id/TextView2"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
权重链.png
Barrier使用
yhx.png如上图:假设有三个控件ABC,C在AB的右边,但是AB的宽是不固定的,这个时候C无论约束在A的右侧,还是约束在B的右侧都是不对,当出现这种情况的时候怎么办? 可以使用Barrier来解决,Barrier 可以在多个控件的一侧建立一个屏障,如下图所示:
yhx.png<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="AAA"
android:textSize="30dp" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:text="BBBBB"
android:textSize="30dp"
app:layout_constraintTop_toBottomOf="@id/TextView1" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="TextView1,TextView2" />
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="CCCCCCC"
android:textSize="30dp"
app:layout_constraintLeft_toRightOf="@+id/barrier"/>
</android.support.constraint.ConstraintLayout>
app:constraint_referenced_ids : 目标控件,可以设置多个(用,隔开)
app:barrierDirection : 位置 bottom ,end , left , right ,start ,top
Group
作用:顾名思义就是一个控件组,就是把多个控件放在一个篮子里。
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="AAA"
android:textSize="30dp" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:text="BBBBB"
android:textSize="30dp"
app:layout_constraintTop_toBottomOf="@id/TextView1" />
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="CCCCCCC"
android:textSize="30dp"
app:layout_constraintTop_toBottomOf="@id/TextView2" />
<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:constraint_referenced_ids="TextView1,TextView3" />
</android.support.constraint.ConstraintLayout>
yhx.png
可以设置android:visibility="invisible" 和android:visibility="gone"都是可以的
app:constraint_referenced_ids :目标控件id
Placeholder 占位符
在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置
<?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=".MainActivity">
<android.support.constraint.Placeholder
android:id="@+id/placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:content="@id/TextView1"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="默认右边"
android:textSize="30dp"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
从上面的代码可以看出 新建Placeholder 在屏幕的左边 ,新建TextView1在屏幕右边,当设置Placeholder 属性android:text="TextView1"时,TextView1就会显示在Placeholder 占位符的里面
yhx.pngGuideline使用
Guildline可以看做是辅助线,在预览的时候帮助你完成布局(不会显示在界面上)。
Guildline的属性:
android:orientation 垂直vertical,水平horizontal
layout_constraintGuide_begin 开始位置
layout_constraintGuide_end 结束位置
layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)
设置app:layout_constraintGuide_begin="50dp
<?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=".MainActivity">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:background="@color/colorPrimary"
android:text="AAAAAA"
android:textSize="30dp" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="50dp" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="设置app:layout_constraintGuide_begin=50dp"
android:textColor="@color/colorAccent"
app:layout_constraintTop_toBottomOf="@id/guideline" />
</android.support.constraint.ConstraintLayout>
当设置app:layout_constraintGuide_begin=50dp时,可以从下图可以看出它的起始位置为屏幕顶部开始。下面有白色间隙,是因为TextView1设置的高度为45dp ,为了把这种效果看的更清楚一点。
yhx.png设置app:layout_constraintGuide_end=50dp
当设置app:layout_constraintGuide_end=50dp时,可以从下图可以看出它的起始位置为屏幕底部开始。下面有白色间隙,是因为TextView1设置的高度为45dp ,为了把这种效果看的更清楚一点。
yhx.png设置app:layout_constraintGuide_percent=0.5
注意app:layout_constraintGuide_percent的取值为0-1
好了,到此为止,ConstraintLayout 基础使用差不多就介绍完了,使用ConstraintLayout 可以看出在布局方面确实可以减少多层嵌套