开发指南
- Relative positioning 相对位置 相对位置是ConstrainLayout中创建布局的基础构建块之一,这些约束允许你定位一个部件相对于另外一个的位置,你可以在水平和垂直轴上约束部件。
水平:left, right, start, end
垂直:top, bottom, text baseline
根据其他控件给自身定位:
layout_toRightOf="A"——>layout_constraintLeft_toRightOf="A"
根据父容器给自身定位:
layout_alignParentRight=true——>layout_constraintRight_toRightOf=parent
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"?>
<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"
android:background="#DAF3FE"
tools:context=".MainActivity"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20"
android:textColor="@color/black"
android:textSize="50sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBaseline_toBaselineOf="@id/tv1"
app:layout_constraintStart_toEndOf="@id/tv1" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text2"
android:gravity="center"
android:text="text2"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@id/text1"
app:layout_constraintTop_toBottomOf="@id/text1"
/>
上面代码中在TextView2里用到了app:layout_constraintLeft_toRightOf="@id/text1"这个属性,他的意思是把TextView2的左边约束到TextView1的右边 ,app:layout_constraintTop_toBottomOf="@id/text1" ,TextView2的顶部约束到TextView1的底部。
app:layout_constraintBottom_toBottomOf="parent" 控件在屏幕底部
两个TextView的高度不一致,但是又希望他们文本对齐,这个时候就可以使用layout_constraintBaseline_toBaselineOf,代码如下:
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:layout_width="100dp"
android:layout_height="50dp"
android:id="@+id/text2"
android:gravity="center"
android:text="text2"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@id/text1"
app:layout_constraintBaseline_toBaselineOf="@id/text1"
/>
- Margins 边距
android:layout_marginStart android:layout_marginEnd android:layout_marginLeft android:layout_marginTop android:layout_marginRight android:layout_marginBottom
Margins属性需要和constraintXXX_toXXX属性配套使用才生效,当相对部件不可见时,Margins属性同样生效
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
android:layout_marginLeft="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text2"
android:gravity="center"
android:text="text2"
app:layout_goneMarginLeft="20dp"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@id/text1"
app:layout_constraintTop_toTopOf="@id/text1"
/>
当TextView1为gone是app:layout_goneMarginLeft="20dp" 生效
3 居中和偏移
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
android:layout_marginLeft="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
ConstraintLayout还提供了另外一种偏移的属性: layout_constraintHorizontal_bias 水平偏移 layout_constraintVertical_bias 垂直偏移
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
android:layout_marginLeft="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.3"
/>
Circular positioning (Added in 1.1)环形位置可以以角度和距离约束一个部件的中心,相对于另一个部件的中心位置,即相对于另一个部件中心的圆形上。
layout_constraintCircle 另一个部件ID
layout_constraintCircleRadius 半径
layout_constraintCircleAngle 角度 (from 0 to 360)
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text1"
android:text="text1"
android:background="@color/blue"
android:gravity="center"
android:layout_marginLeft="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/text2"
android:gravity="center"
android:text="text2"
app:layout_constraintCircle ="@id/text1"
app:layout_constraintCircleRadius="150dp"
app:layout_constraintCircleAngle ="150"
app:layout_goneMarginLeft="20dp"
android:background="@color/qmui_config_color_red"
tools:ignore="MissingConstraints" />
宽高比 当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比,举个例子:
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
复制代码宽设置为0dp,宽高比设置为1:1,这个时候TextView1是一个正方形,效果如下:
除此之外,在设置宽高比的值的时候,还可以在前面加W或H,分别指定宽度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3
4权重比使用
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="100dp"
android:text="TextView1"
android:background="@color/green"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2"
app:layout_constraintHorizontal_weight="2" />
<TextView
android:id="@+id/TextView2"
android:layout_width="0dp"
android:layout_height="100dp"
android:text="TextView2"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_weight="3" />
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:text="TextView3"
android:background="@color/blue"
android:layout_height="100dp"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_weight="4" />
layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是: CHAIN_SPREAD —— 展开元素 (默认); CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent; CHAIN_PACKED —— 链的元素将被打包在一起。 如图所示:
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="TextView1"
android:background="@color/green"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2"
app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="TextView2"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:text="TextView3"
android:background="@color/blue"
android:layout_height="100dp"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
CHAIN_SPREAD_INSIDE —— 展开元素
CHAIN_PACKED
5 WRAP_CONTENT enforcing constraints (Added in 1.1) 在1.1前,设置wrap_content属性,会被视为文字尺寸,即约束不会限制结果尺寸。通常这已经足够(更快)。有些情况,仍然希望强制执行约束限制结果尺寸,这种情况,可以使用新的属性。
app:layout_constrainedWidth="true|false" app:layout_constrainedHeight="true|false"
<TextView
android:id="@+id/TextView1"
android:layout_width="150dp"
android:layout_height="150dp"
android:text="TextView1"
android:background="@color/green"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="TextView2TextView2TextView2TextView2TextView2TextView2TextView2TextView2TextView2"
android:background="@color/qmui_config_color_red"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toRightOf="parent"
/>
<!-- 增加app:layout_constrainedWidth="true"属性后 -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="172dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_marginTop="15dp"
android:background="@color/cardview_dark_background"
android:text="TextViTexew"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:background="@color/design_default_color_primary"
android:text="aaaaaaaaaaaaaaaaaaa"
app:layout_constraintEnd_toStartOf="@+id/textView3"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"
android:background="@color/cardview_shadow_start_color"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView2"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
6 辅助工具
Barrier
假设有3个控件ABC,C在AB的右边,但是AB的宽是不固定的,这个时候C无论约束在A的右边或者B的右边都不对。当出现这种情况可以用Barrier来解决。Barrier可以在多个控件的一侧建立一个屏障,如下所示:
<TextView
android:id="@+id/TextView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/green"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/TextView2"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/qmui_config_color_red"
app:layout_constraintTop_toBottomOf="@id/TextView1"
app:layout_constraintLeft_toLeftOf="@id/TextView1"/>
<androidx.constraintlayout.widget.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="100dp"
android:background="@color/yellow"
android:text="我爱你爱着你就像老鼠爱大米,我爱你爱着你就像老鼠爱大米"
app:layout_constrainedWidth="true"
app:layout_constraintLeft_toRightOf="@+id/barrier"
app:layout_constraintRight_toRightOf="parent"/>
Group可以把多个控件归为一组,方便隐藏或显示一组控件,举个例子:
<androidx.constraintlayout.widget.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:constraint_referenced_ids="TextView1,TextView3" />
MATCH_CONSTRAINT尺寸(在1.1中添加)
当一个view的长宽设置为MATCH_CONSTRAINT(即0dp)时,默认是使该view占用所有的可用的空间. 这里有几个额外的属性
layout_constraintWidth_min和layout_constraintHeight_min:将设置此维度的最小大小
layout_constraintWidth_max和layout_constraintHeight_max:将设置此维度的最大大小
layout_constraintWidth_percent和layout_constraintHeight_percent:将此维度的大小设置为父级的百
<Button
android:id="@+id/btn1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Q"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_percent="0.5"/>
Guideline可以创建相对于ConstraintLayout的水平或者垂直准线. 这根辅助线,有时候可以帮助我们定位.
layout_constraintGuide_begin 距离父亲起始位置的距离(左侧或顶部)
layout_constraintGuide_end 距离父亲结束位置的距离(右侧或底部)
layout_constraintGuide_percent 距离父亲宽度或高度的百分比(取值范围0-1)
复制代码我们拿辅助线干嘛??? 比如有时候,可能会有这样的需求,有两个按钮,在屏幕中央一左一右. 如果是以前的话,我会搞一个LinearLayout,.然后将LinearLayout居中,然后按钮一左一右.
<!--水平居中-->
<android.support.constraint.Guideline
android:id="@+id/gl_center"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
app:layout_constraintEnd_toStartOf="@id/gl_center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
app:layout_constraintLeft_toRightOf="@id/gl_center"/>