ConstraintLayout必知必会

749 阅读4分钟

1.约束属性

  • app:layout_constraintStart_toStartOf:将视图的起始边与给定视图的起始边对齐。
  • app:layout_constraintEnd_toEndOf:将视图的结束边与给定视图的结束边对齐。
  • app:layout_constraintTop_toTopOf:将视图的顶部边与给定视图的顶部边对齐。
  • app:layout_constraintBottom_toBottomOf:将视图的底部边与给定视图的底部边对齐。
  • app:layout_constraintBaseline_toBaselineOf:将视图的基线与给定视图的基线对齐。
  • app:layout_constraintHorizontal_bias:设置视图在水平方向上的偏移比例,范围为0-1。
  • app:layout_constraintVertical_bias:设置视图在垂直方向上的偏移比例,范围为0-1。
  • app:layout_constraintHorizontal_chainStyle:设置水平链条的排列方式。
  • app:layout_constraintVertical_chainStyle:设置垂直链条的排列方式。

2.chainStyle

三个按钮左右相互依赖,两边依赖父控件,默认平分4个剩余横向空间

<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:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".ConstraintLayoutActivity">

  <Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="A"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/btn2"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

  <Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="B"
    app:layout_constraintEnd_toStartOf="@+id/btn3"
    app:layout_constraintStart_toEndOf="@+id/btn1"
    app:layout_constraintTop_toTopOf="@+id/btn1" />

  <Button
    android:id="@+id/btn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="C"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/btn2"
    app:layout_constraintTop_toTopOf="@+id/btn2" />

</androidx.constraintlayout.widget.ConstraintLayout>

packed

紧凑排列,三个控件链接在一起横向居中

在第一个控件添加 app:layout_constraintHorizontal_chainStyle="packed", 只能在表头添加有效。

spread_inside

平均分布,两边靠边

在第一个控件添加 app:layout_constraintHorizontal_chainStyle="spread_inside", 只能在表头添加有效。

spread

平均分布

在第一个控件添加 app:layout_constraintHorizontal_chainStyle="spread", 只能在表头添加有效。

3.水平权重

第一步:将左右View相互链在一起成等比的view

使用 layout_constraintHorizontal_weight=''1 等分view的宽度

<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:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".ConstraintLayoutActivity">

  <TextView
    app:layout_constraintHorizontal_weight="1"
    android:layout_marginBottom="100dp"
    android:textSize="20dp"
    android:background="#0f0"
    android:id="@+id/tv1"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintBottom_toBottomOf="parent"
    android:text="A"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tv2"
    android:layout_width="0dp"
    android:layout_height="50dp"/>

  <TextView
    app:layout_constraintHorizontal_weight="2"
    android:textSize="20dp"
    android:background="#2196F3"
    android:id="@+id/tv2"
    app:layout_constraintStart_toEndOf="@+id/tv1"
    app:layout_constraintTop_toTopOf="@+id/tv1"
    app:layout_constraintEnd_toStartOf="@+id/tv3"
    android:text="B"
    android:layout_width="0dp"
    android:layout_height="50dp" />
  <TextView
    app:layout_constraintHorizontal_weight="1"
    android:textSize="20dp"
    android:background="#FFC107"
    android:id="@+id/tv3"
    app:layout_constraintStart_toEndOf="@+id/tv2"
    app:layout_constraintTop_toTopOf="@+id/tv2"
    app:layout_constraintEnd_toEndOf="parent"
    android:text="C"
    android:layout_width="0dp"
    android:layout_height="50dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

垂直同上 属性:layout_constraintVertical_weight="1"

4.百分比布局

layout_constraintHeight_percent="0.15" 设置控件占屏幕的高度

<androidx.constraintlayout.widget.ConstraintLayout
  android:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <ImageView
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:background="#0f0"
    app:layout_constraintHeight_percent="0.15"
    android:layout_width="0dp"
    android:layout_height="0dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

app:layout_constraintVertical_bias="0"

若将上面的ImageView加入app:layout_constraintBottom_toBottomOf="parent",控件就会居中显示

加入layout_constraintVertical_bias偏移量0就会相对垂直向下的偏移量为0,不会将控件约束到中间位置,和上图6显示效果一致

5.文本基线

如果两个文本大小不一致,需要使两个文本对应底部基线在一条线上,使用layout_constraintBaseline_toBaselineOf 属性

<androidx.constraintlayout.widget.ConstraintLayout
  android:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <TextView
    android:layout_marginStart="100dp"
    android:id="@+id/tv1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:text="1200"
    android:textSize="40sp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
  <TextView
    app:layout_constraintBaseline_toBaselineOf="@+id/tv1"
    app:layout_constraintBottom_toBottomOf="@+id/tv1"
    app:layout_constraintStart_toEndOf="@+id/tv1"
    app:layout_constraintTop_toTopOf="@+id/tv1"
    android:text="元"
    android:textSize="10sp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>

5.动态控制子元素

<?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:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".ConstraintLayoutActivity">

  <TextView
    android:id="@+id/img"
    android:layout_width="180dp"
    android:layout_height="180dp"
    android:layout_marginTop="100dp"
    android:background="#FF5722"
    android:gravity="center"
    android:textColor="#fff"
    android:textSize="30sp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

  <Button
    android:id="@+id/horizontal_bias"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="水平偏移"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

  <Button
    android:id="@+id/vertical_bias"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:text="垂直偏移"
    app:layout_constraintStart_toEndOf="@+id/horizontal_bias"
    app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

点击水平偏移和垂直偏移分别向右和向下一段位置,通过设置ConstraintSet来改变子元素的偏移量

var offsetHorizontal= 0.1f
var offsetVertical= 0.1f
val constraintLayout = findViewById<ConstraintLayout>(R.id.constraintLayout)
findViewById<Button>(R.id.horizontal_bias).setOnClickListener {
    val set = ConstraintSet()
    set.clone(constraintLayout)
    //设置子元素horizontalBias
    offsetHorizontal+=0.1f
    set.setHorizontalBias(R.id.img,offsetHorizontal)
    //应用新的约束
    set.applyTo(constraintLayout)
}
findViewById<Button>(R.id.vertical_bias).setOnClickListener {
    val set = ConstraintSet()
    set.clone(constraintLayout)
    //设置子元素verticalBias
    offsetVertical+=0.1f
    set.setVerticalBias(R.id.img,offsetVertical)
    //应用新的约束
    set.applyTo(constraintLayout)
}