前言
约束布局ConstraintLayout 是一个ViewGroup,可以在Api9 以上的Android系统使用它,它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout。
开始使用
添加依赖
implementation ‘com.android.support.constraint:constraint-layout:1.1.3’
一.ConstraintLayout 替代RelativeLayout
1.相对定位的常用属性:
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
例子:layout_constraintLeft_toRightOf,即把textView2的左面约束到textView1的右边。
<?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"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView1"
android:layout_width="100dp"
android:background="@color/colorPrimaryDark"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="555"
android:background="@color/colorPrimary"
app:layout_constraintLeft_toRightOf="@+id/textView1"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
2.相对于父组件的对应关系属性
即布局相对于父布局的相对位置
<?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"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView1"
android:layout_width="100dp"
android:background="@color/colorPrimaryDark"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
如上,即textview1控件在父布局的上方和左方
3.角度偏移
app:layout_constraintCircle="@+id/xx"
app:layout_constraintCircleAngle="60"(角度)
app:layout_constraintCircleRadius="30dp"(距离)
4.尺寸约束
控件的尺寸可以通过四种不同方式指定:
- 用指定的尺寸
- 使用wrap_content,让控件自己计算大小
当控件的高度或宽度为wrap_content时,可以使用下列属性来控制最大、最小的高度或宽度:
android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度 - 使用 0dp (MATCH_CONSTRAINT)
- 宽高比 (layout_constraintDimensionRatio)
二.ConstraintLayout 替代LinearLayout
1.权重weight 特性
主要用到属性 layout_constraintHorizontal_weight,示例
<?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="wrap_content">
<TextView
android:id="@+id/TextView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#22000000"
android:text="12"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/TextView2"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/TextView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#55000000"
android:text="34"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintLeft_toRightOf="@+id/TextView1"
app:layout_constraintRight_toLeftOf="@+id/TextView3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/TextView3"
android:layout_width="0dp"
android:text="56"
android:layout_height="wrap_content"
android:background="#11000000"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="3"
app:layout_constraintLeft_toRightOf="@+id/TextView2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果图
三.对其Gone的处理
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
示例:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView1"
android:layout_width="100dp"
android:background="@color/colorPrimaryDark"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/textView2"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="555"
android:background="@color/colorPrimary"
app:layout_constraintLeft_toRightOf="@+id/textView1"
app:layout_goneMarginLeft="20dp"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
效果
如果将textview1设置属性
android:visibility=“gone”
则效果图为,textview2左边距为20dp
四.辅助工具
1.辅助线(Guideline)
在布局界面的时候可以充分利用横向的或者纵向的Guideline,对齐布局里面的View
属性
- layout_constraintGuide_percent 即按照百分比设置边距,这个值的范围是0-1。(0% - 100%)
创建Guideline
添加横竖两条之后,再加入我们的buttom来对齐,同时入宫辅助线距离改变,buttom的位置也随之改变。
2.辅助线(Guideline)
Barrier 是一个虚拟视图,类似于 Guideline,用来约束对象。Barrier 和 Guideline 的区别在于它是由多个 view 的大小决定的。它跟 Guideline 属于Virtual Helper objects,但是比Guideline实用。
示例,
假设有3个控件textView1,textView2,textView3,textView3在textView1,2的右边,但是textView1,2的宽是不固定的,这个时候textView3无论约束在textView1的右边或者textView2的右边都不对。当出现这种情况可以用Barrier来解决。Barrier可以在多个控件的一侧建立一个屏障,如下所示:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="12132213213"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="12321321sd213123213"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<android.support.constraint.Barrier
android:id="@+id/barrier7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView2,textView1" />
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="23123213"
app:layout_constraintStart_toEndOf="@+id/barrier7"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
效果图:
textview1与teview2被barrier7隔着一道屏障,textView3在屏障右边,这样,即使左边的文字变多也不会越过这个屏障,只会让这道屏障向右推移,符合我们的预期。
3.组 Group
Group可以把多个控件归为一组,方便隐藏或显示一组控件,举个例子:
<?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:orientation="vertical">
<androidx.constraintlayout.widget.Group
android:id="@+id/group2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="button12,button13"/>
<Button
android:id="@+id/button12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="84dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Button"
app:layout_constraintEnd_toStartOf="@+id/button13"
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_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/button12" />
</androidx.constraintlayout.widget.ConstraintLayout>