ConstraintLayout(约束布局)的使用

简介

ConstraintLayout是Android Studio 2.2中主要的新增功能之一。

它和传统编写界面的方式恰恰相反,ConstraintLayout非常适合使用可视化的方式来编写界面,但并不太适合使用XML的方式来进行编写。当然,可视化操作的背后仍然还是使用的XML代码来实现的,只不过这些代码是由Android Studio根据我们的操作自动生成的。

另外,ConstraintLayout还有一个优点,它可以有效地解决布局嵌套过多的问题。我们平时编写界面,复杂的布局总会伴随着多层的嵌套,而嵌套越多,程序的性能也就越差。ConstraintLayout则是使用约束的方式来指定各个控件的位置和关系的,它有点类似于RelativeLayout,但远比RelativeLayout要更强大。

使用

基本操作

可视化编写

可以利用拖拽的方式加入一个控件,并且在design界面设置一些基本属性。详细操作可参考郭神的这篇文章

XML编写

当然,除了拖拽外,也可以在xml里面直接用代码来编写,如何编写可参考洋神的这篇文章

进阶操作

利用宽高比设置控件大小

app:layout_constraintDimensionRatio:设置宽高比。例如app:layout_constraintDimensionRatio=”16 : 9”表示宽高比为16比9

1
2
3
4
5
6
7
8
9
10
11
12
13
<TextView
android:id="@+id/banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_light"
android:gravity="center"
android:hapticFeedbackEnabled="false"
android:text="banner"
android:textColor="@android:color/black"
app:layout_constraintDimensionRatio="16 : 9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

效果如下:

利用比例设置控件大小

要设置水平方向上的比例可以使用app:layout_constraintHorizontal_weight属性,使用该属性时layout_width设为0dp。例如设置3个宽度比为2:1:1的tab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<TextView
android:id="@+id/tab1"
android:layout_width="0dp"
android:layout_height="32dp"
android:text="tab1"
android:gravity="center"
android:background="@android:color/holo_blue_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/tab2"
app:layout_constraintHorizontal_weight="2"/>

<TextView
android:id="@+id/tab2"
android:layout_width="0dp"
android:layout_height="32dp"
android:text="tab2"
android:gravity="center"
android:background="@android:color/holo_orange_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tab3"
app:layout_constraintStart_toEndOf="@+id/tab1"
app:layout_constraintHorizontal_weight="1"/>

<TextView
android:id="@+id/tab3"
android:layout_width="0dp"
android:layout_height="32dp"
android:text="tab3"
android:gravity="center"
android:background="@android:color/holo_red_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tab2"
app:layout_constraintHorizontal_weight="1"/>

效果如下:

利用比例设置控件左右(上下)间隔

利用app:layout_constraintHorizontal_bias属性来设置水平方向上左右间隔的比例。app:layout_constraintVertical_bias同理。例如设置属性app:layout_constraintHorizontal_bias = 0.9表示左右间隔的比例为9 : 1。效果如下:

利用app:layout_constraintHorizontal_chainStyle属性来控制链的样式。

什么是链?如果两个或以上控件通过下图的方式约束在一起,就可以认为是他们是一条链(图为横向的链,纵向同理)。

例如上面的3个tab就是一条链。一条链的第一个控件就是这条链的链头(例如上面的tab1),对链头设置app:layout_constraintHorizontal_chainStyle属性,可以设置这条链的样式。有3种样式可以选择:spread、spread_inside、packed。

spread(默认):展开元素
spread_inside:展开元素,但链的两端紧靠两边
packed:将元素打包在一起

假设三个tab的宽度分别为100dp、50dp、100dp。

  1. tab1不显示设置app:layout_constraintHorizontal_chainStyle属性,则其该属性为默认的spread
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <TextView
    android:id="@+id/tab1"
    android:layout_width="100dp"
    android:layout_height="64dp"
    android:text="tab1"
    android:gravity="center"
    android:background="@android:color/holo_blue_light"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/tab2"/>

    <TextView
    android:id="@+id/tab2"
    android:layout_width="50dp"
    android:layout_height="64dp"
    android:text="tab2"
    android:gravity="center"
    android:background="@android:color/holo_orange_light"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/tab3"
    app:layout_constraintStart_toEndOf="@+id/tab1" />

    <TextView
    android:id="@+id/tab3"
    android:layout_width="100dp"
    android:layout_height="64dp"
    android:text="tab3"
    android:gravity="center"
    android:background="@android:color/holo_red_light"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/tab2" />

效果如下:

  1. tab1的app:layout_constraintHorizontal_chainStyle属性设置为spread_inside,其他不变。效果如下:

  1. tab1的app:layout_constraintHorizontal_chainStyle属性设置为packed,其他不变。效果如下:

最后补充一下,如果tab的宽度不是固定值,而是比例的话,3种样式的效果是一样的。

防止约束失效

如果控件的宽设置为wrap_content时,如果实际宽度超过了约束的最大宽度,那么约束会失效(高同理)。为了防止约束失效,可以使用app:layout_constrainedWidth属性,设置app:layout_constrainedWidth=”true”即可。

举个例子,假设水平方向上有两个TextView,右边的TextView长度固定,左边的TextView长度不定。

当左边的内容长度合适的时候没有问题

但当左边的内容过长的时候,会把右边的TextView覆盖掉。

解决方法是给左边的TextView设置app:layout_constrainedWidth=”true”,防止其约束失效,最后效果如下:

参考

-------------    本文到此结束  感谢您的阅读    -------------
0%