写在前面: ConstraintLayout 的基本应用本文就不做介绍了,已经有很多不错的文章供大家可以参考,这里只介绍相对高级的使用。
参考文章
bias (来对当前控件定位置比例的)
假如我们当前控件是 横向约束(即左边和右边都有约束),我们想让当前控件 在 横坐标 的 中间位置开始显示,我们就可以设置 app:layout_constraintHorizontal_bias="0.75"
,这样控件两边的空间 比例 为 3:1
<Button
android:id="@+id/button9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="8dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
圆形定位
layout_constraintCircle : references another widget id (参考的控件)
layout_constraintCircleRadius : the distance to the other widget center (圆的半径)
layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360) (圆的旋转角度)
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="TextView5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView6"
app:layout_constraintCircle="@id/textView5"
app:layout_constraintCircleAngle="60"
app:layout_constraintCircleRadius="100dp"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="246dp"
tools:layout_editor_absoluteY="205dp" />
设置当前控件宽高占父控件的百分比
假设要设置一个控件,其高度是父布局的1/2,那么首先要做的是:
1 将其高度设置为 match_constraint
2 设置自身高度是占父布局高度的百分比。
3 指定自己的百分比。
依次设置
- android:layout_height=“0dp”
- app:layout_constraintHeight_default=“percent”
- app:layout_constraintHeight_percent=“0.5”
这样就可以了
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="TextView6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHeight_default="percent"
app:layout_constraintWidth_default="percent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintWidth_percent="0.5"
/>
Ratio 设置当前控件的宽高比率
- 我们可以设置当前控件的宽高比例。但是有个前提,就是宽和高的指定至少有一方是0dp。
- 第二个按钮,用“H”表示以高度为约束,高度的最大尺寸就是父控件的高度,“2:1”表示高:宽 = 2 : 1.
则宽度为高度的一半。 - 第三个按钮,用“W”表示以高度为约束,宽度的最大尺寸就是父控件的高度,“2:1”表示宽:高 = 2 : 1.
则高度为宽度的一半。
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="68dp"
android:layout_marginTop="8dp"
android:text="TextView6"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button11"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginStart="84dp"
android:layout_marginTop="52dp"
android:text="TextView6"
app:layout_constraintDimensionRatio="H,2:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/button10"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="132dp"
android:layout_marginEnd="8dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintDimensionRatio="W,2:1"
app:layout_constraintTop_toBottomOf="@+id/button11" />
链条(Chains)
- 类似于 H5 中的 flex伸缩布局
- 设置 width=0,且控件之间两两互相约束,即可实现水平方向等分。此时还可以给控件设置 layout_constraintHorizontal_weight 属性,该属性与 LinearLayout 中的 weight 类似。
链条头部的属性
水平链的最左边,垂直链的最上边称之为头部,链的头部可以设置链的属性:
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintVertical_chainStyle="packed"
- spread 默认属性,平均分布
- spread_inside 首尾无间距
- packed 控件间无间距,可以同时搭配 layout_constraintHorizontal_bias 属性控制与父容器的间距
应用1 同一行 等间分布
<Button
android:id="@+id/button12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="88dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/button13"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button12"
app:layout_constraintEnd_toStartOf="@+id/button14"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button12"
app:layout_constraintTop_toTopOf="@+id/button12" />
<Button
android:id="@+id/button14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button13"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button13"
app:layout_constraintTop_toTopOf="@+id/button13" />
chain style packed
<Button
android:id="@+id/button12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="68dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/button13"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button12"
app:layout_constraintEnd_toStartOf="@+id/button14"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button12"
app:layout_constraintTop_toTopOf="@+id/button12"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="@+id/button14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button13"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button13"
app:layout_constraintTop_toTopOf="@+id/button13"
app:layout_constraintVertical_bias="1.0" />
chain style spread_inside
<Button
android:id="@+id/button12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="68dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/button13"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button12"
app:layout_constraintEnd_toStartOf="@+id/button14"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button12"
app:layout_constraintTop_toTopOf="@+id/button12"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="@+id/button14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button13"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button13"
app:layout_constraintTop_toTopOf="@+id/button13"
app:layout_constraintVertical_bias="1.0" />
加权链(Weighted chains)
- 注意 要加权时, width 必须为 “0dp”; 否则无效
<Button
android:id="@+id/button12"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="68dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/button13"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_weight="3"/>
<Button
android:id="@+id/button13"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button12"
app:layout_constraintEnd_toStartOf="@+id/button14"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button12"
app:layout_constraintTop_toTopOf="@+id/button12"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintHorizontal_weight="2"/>
<Button
android:id="@+id/button14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button13"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button13"
app:layout_constraintTop_toTopOf="@+id/button13"
app:layout_constraintVertical_bias="1.0" />
指示线 Guideline
不会被显示,仅仅用于辅助布局
- guideLine可以使控件之间对称
定位Guideline有三种方式:
- 指定距离左侧或顶部的固定距离(layout_constraintGuide_begin)
- 指定距离右侧或底部的固定距离(layout_constraintGuide_end)
- 指定在父控件中的宽度或高度的百分比(layout_constraintGuide_percent)
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<Button
android:id="@+id/button15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
android:layout_marginEnd="40dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="@+id/button15" />
目标控件是gone的时候,怎么margin?
正常情况下是这样,当地一个 button 设置为 gone时,宽高都会变为0,但是根据他限制的元素依然会根据它限制,所以出现了这样的情况。
<Button
android:id="@+id/button17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="128dp"
android:text="Button"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@+id/button18"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button18"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button17"
app:layout_constraintEnd_toStartOf="@+id/button19"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button17"
app:layout_constraintTop_toTopOf="@+id/button17" />
<Button
android:id="@+id/button19"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="@+id/button18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button18"
app:layout_constraintTop_toTopOf="@+id/button18" />
解决方案
使用 goneMargin
,
当前View与另一个View绑定后,另一个View的属性设置为了Gone,则以下属性会生效
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
<TextView
android:id="@+id/textView3"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="140dp"
android:layout_marginTop="16dp"
android:text="TextView3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="16dp"
android:text="TextView4"
app:layout_constraintStart_toEndOf="@+id/textView3"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginLeft="290dp" />